深入解析-正则表达式
学习正则,我们到底要学什么?
正则表达式(RegEx)是一种强大的文本匹配工具,广泛应用于数据验证、文本搜索、替换和解析等领域。学习正则表达式,我们不仅要掌握其语法规则,还需要学会如何高效地利用正则来解决实际问题,避免复杂的模式导致性能问题。
核心目标:
- 理解正则表达式的基本构成与工作原理。
- 熟悉常见的正则元字符、量词、分组等基本构成要素。
- 掌握如何高效地构建正则表达式来处理各种文本问题。
1. 元字符:如何巧妙记忆正则表达式的基本元件?
正则表达式的基本构成是元字符,它们代表了字符的匹配规则。常见的元字符包括:
.
:匹配任意字符(除了换行符)\d
:匹配任何数字字符(0-9)\w
:匹配字母、数字及下划线([a-zA-Z0-9_])\s
:匹配任何空白字符(如空格、制表符、换行符)[]
:定义一个字符集,匹配字符集中的任意一个字符。
示例:
// 示例:匹配任意一个数字
String regex = "\\d";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher("a3b");
while (matcher.find()) {System.out.println("找到数字: " + matcher.group());
}
输出:
找到数字: 3
记忆技巧:
.
就像一个万能的“通配符”。\d
对应数字,\w
对应字母和数字。[]
是字符集,用来指定一组匹配条件。
2. 量词与贪婪:小小的正则,也可能把 CPU 拖垮!
量词用于指定某个元素出现的次数。常见的量词包括:
*
:表示前面的元素可以重复零次或多次(贪婪模式)。+
:表示前面的元素至少出现一次。?
:表示前面的元素出现零次或一次。
示例:
// 贪婪模式:匹配多个字符
String regex = "a.*b"; // 贪婪模式,匹配从 'a' 到 'b' 之间的所有字符
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher("a1b2c3b");
while (matcher.find()) {System.out.println("匹配到: " + matcher.group());
}
输出:
匹配到: a1b2c3b
贪婪模式会尽可能多地匹配字符,可能导致性能问题。为避免这种情况,可以使用非贪婪模式(*?
, +?
)。
// 非贪婪模式:匹配最小的字符集
String regex = "a.*?b"; // 非贪婪模式,匹配最短的 'a' 到 'b' 之间的字符
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher("a1b2c3b");
while (matcher.find()) {System.out.println("匹配到: " + matcher.group());
}
输出:
匹配到: a1b
3. 分组与引用:如何实现更复杂的查找替换操作?
分组用于将正则表达式中的部分内容封装在括号中,这样我们就可以对匹配的部分进行引用或者替换。
示例:
// 使用分组进行文本替换
String regex = "(\\d+)-(\\d+)";
String replacement = "$2-$1"; // 引用第二个分组和第一个分组
String input = "123-456";
String output = input.replaceAll(regex, replacement);
System.out.println(output); // 输出: 456-123
解释:(\\d+)-(\\d+)
会匹配由数字组成的两个部分并用 ()
分组。在替换中,$1
和 $2
分别代表第一个和第二个分组。
4. 匹配模式:带你一次性掌握常见的 4 种匹配模式
常见的四种匹配模式包括:
- 默认模式:按行匹配。
Pattern.CASE_INSENSITIVE
:忽略大小写。Pattern.DOTALL
:.
可以匹配换行符。Pattern.MULTILINE
:^
和$
可以匹配行的开头和结尾。
示例:
String regex = "^[a-z]+$";
String input = "hello";
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(input);
System.out.println(matcher.matches()); // 输出: true
解释:该正则表达式匹配的是由小写字母组成的整个字符串,使用 Pattern.CASE_INSENSITIVE
忽略大小写。
5. 断言:如何用位置匹配更好地实现替换重复单词?
断言(Assertions)是正则表达式中一种特殊的工具,用于根据位置或条件进行匹配。断言分为两种:
- 正向断言:
(?=...)
用来匹配某个位置后满足条件的字符串。 - 负向断言:
(?!...)
用来匹配某个位置后不满足条件的字符串。
应用场景:
- 用于避免重复单词的匹配,或者仅在某个条件满足时进行匹配。
示例:
// 去除重复单词,使用正向断言
String regex = "\\b(\\w+)\\b(?=.*?\\b\\1\\b)";
String input = "hello world hello java world java";
String output = input.replaceAll(regex, "");
System.out.println(output); // 输出: "world java"
解释:
\\b
:单词边界,确保匹配的是完整的单词。(\\w+)
:匹配一个或多个字母数字字符,并将其捕获为组1。(?=.*?\\b\\1\\b)
:正向断言,确保后面还有该单词出现。
6. 转义:在正则表达式中转义需要注意哪些问题?
转义字符在正则表达式中非常重要,许多元字符(如.
、*
、[
、]
等)在没有转义的情况下有特殊含义。如果我们想要匹配这些字符本身,就需要使用反斜杠进行转义。
常见转义字符:
\\
用于匹配反斜杠本身。\\.
用于匹配句点(.
)字符,而非任意字符。\\[
和\\]
用于匹配方括号[
和]
。
示例:
// 匹配点号
String regex = "\\.";
String input = "example.com";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
System.out.println(matcher.find()); // 输出: true
注意事项:
- 在字符串中,反斜杠是转义字符,所以下划线
\
需要写成\\
。 - 在某些情况下,正则中的转义字符需要额外小心,尤其是在不同的编程语言和库中,反斜杠的处理可能略有不同。
7. 正则有哪些常见的流派及其特性?
正则表达式的实现方式有不同的流派,主要包括以下几种:
- NFA(非确定性有限自动机):大多数现代正则引擎采用NFA模式,即正则引擎通过回溯来寻找匹配,比较灵活,但性能可能受到影响,尤其在遇到复杂或贪婪的模式时。
- DFA(确定性有限自动机):DFA正则引擎一次性扫描所有可能的匹配,效率较高,但表达能力较弱,通常不支持回溯。
- POSIX:POSIX规范是UNIX系统中的标准正则表达式实现,具有严格的语法要求,支持常规的正则操作,但不支持更复杂的功能。
不同的流派在正则表达式的匹配效率、灵活性以及表达能力上有所不同,开发人员在选择时需要根据实际的需求进行权衡。
8. 应用 1:正则如何处理 Unicode 编码的文本?
Unicode 是一种字符编码标准,支持全球大部分文字和符号。正则表达式也可以处理Unicode编码的文本,但需要注意匹配模式和字符类别。
常见问题:
- 在正则表达式中,默认匹配的是单字节字符。若需要处理Unicode字符集中的多字节字符(如中文),需要指定Unicode匹配模式。
\p{}
可以用来匹配特定Unicode字符类别,如字母、数字等。
示例:
// 匹配所有汉字字符
String regex = "\\p{IsHan}+";
String input = "Hello 你好 World";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {System.out.println(matcher.group()); // 输出: 你好
}
解释:
\\p{IsHan}
:匹配汉字字符类别。
9. 应用 2:如何在编辑器中使用正则完成工作?
许多现代文本编辑器(如 VSCode、Sublime Text)都支持正则表达式来查找和替换文本。这对于处理大量文本、日志分析、代码重构等任务非常有用。
示例:
-
查找所有变量定义:
假设你想查找所有的 Java 变量定义,可以使用类似\b\w+\s+\w+\b
的正则来匹配。 -
替换函数调用中的参数:
假设你想替换函数调用的参数格式,可以使用正则替换。比如,将foo(a, b)
替换成foo(a; b)
。
10. 应用 3:如何用正则让文本处理能力上一个台阶?
正则表达式可以极大地增强文本处理能力,尤其是对复杂文本的处理。你可以利用正则来解析复杂的日志、抓取网页内容、进行数据验证等。
应用场景:
- 日志分析:通过正则提取日志中的关键字段,例如日期、错误代码、日志级别等。
- Web Scraping:使用正则从网页中提取数据,例如标题、文章内容等。
示例:
// 从日志中提取错误信息
String regex = "ERROR\\s+(\\d+)\\s+(.+)";
String input = "ERROR 404 Page Not Found\nERROR 500 Internal Server Error";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {System.out.println("错误代码: " + matcher.group(1)); // 输出错误代码System.out.println("错误信息: " + matcher.group(2)); // 输出错误描述
}
11. 如何理解正则表达式的匹配原理以及优化原则?
理解正则表达式的匹配原理是掌握其高效应用的关键。正则表达式的匹配过程通常是通过 有限状态机(FSM) 来实现的。正则引擎从左到右扫描输入字符串,并尝试与正则模式匹配。在匹配过程中,正则引擎会执行以下步骤:
- 字符匹配:每次尝试匹配输入字符串的一个字符。
- 回溯:当匹配失败时,正则引擎会回溯到上一个匹配位置,重新尝试匹配其他可能的模式。
- 正向搜索:正则引擎通常会从字符串的左侧开始扫描,遇到第一个符合条件的匹配时就停止。
优化原则:
- 避免使用贪婪量词:贪婪量词会尝试匹配尽可能多的字符,这可能导致性能下降,特别是在长字符串中。可以使用非贪婪量词(
*?
,+?
)来减少匹配范围。 - 使用 anchors(锚点):通过
^
和$
来限制匹配的起始和结束位置,避免正则引擎遍历整个字符串。 - 精简表达式:避免使用过多的分组和不必要的重复模式,以减小匹配时间。
示例:
// 贪婪匹配 vs 非贪婪匹配
String regex1 = "a.*b"; // 贪婪模式,尽量匹配更多字符
String regex2 = "a.*?b"; // 非贪婪模式,尽量匹配较少字符String input = "a1b2c3b";
Pattern pattern1 = Pattern.compile(regex1);
Pattern pattern2 = Pattern.compile(regex2);Matcher matcher1 = pattern1.matcher(input);
Matcher matcher2 = pattern2.matcher(input);System.out.println(matcher1.find()); // 输出: true, 匹配到 a1b2c3b
System.out.println(matcher2.find()); // 输出: true, 匹配到 a1b
优化建议:
- 在需要匹配到特定字符的情况下,尽量使用精确的匹配方式而不是广泛的通配符。
- 对于有大量文本需要匹配的情况,避免使用像
.*
这样的模式,改用更具体的匹配条件,如\d+
来限制匹配数字。
12. 问题集锦:详解正则表达式常见问题及解决方案
在使用正则表达式时,常常会遇到一些特定问题。这里列举了几个常见的正则问题,并提供解决方案。
-
问题:如何处理多行文本的匹配?
- 默认情况下,正则表达式只会匹配单行文本。如果需要匹配多行文本,可以使用
Pattern.MULTILINE
标志。
示例:
String regex = "^hello"; // 匹配以 hello 开头的行 String input = "hello world\nhello java\ngoodbye world"; Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); Matcher matcher = pattern.matcher(input);while (matcher.find()) {System.out.println("匹配到: " + matcher.group()); }
输出:
匹配到: hello 匹配到: hello
- 默认情况下,正则表达式只会匹配单行文本。如果需要匹配多行文本,可以使用
-
问题:如何处理复杂的文本替换?
- 对于复杂的文本替换,可以使用正则表达式中的分组和引用来精确替换指定部分。
示例:
// 替换日期格式:yyyy-mm-dd -> dd/mm/yyyy String regex = "(\\d{4})-(\\d{2})-(\\d{2})"; String replacement = "$3/$2/$1"; // $1, $2, $3 表示捕获组 String input = "2021-12-31"; String output = input.replaceAll(regex, replacement); System.out.println(output); // 输出: 31/12/2021
-
问题:正则表达式匹配时如何避免死循环?
- 贪婪模式可能会导致正则引擎在一些情况下陷入死循环,特别是当模式中存在大量回溯时。优化贪婪模式,避免不必要的回溯。
解决方案:
- 使用非贪婪量词
*?
或+?
,使得匹配尽可能小。 - 使用预设的匹配条件,如限定范围
[a-z]{3,10}
来防止过多回溯。
13. 正则表达式的性能优化
正则表达式的性能是我们在实际应用中必须关注的一个重要方面,尤其是在大数据量或复杂模式匹配的情况下。如果正则表达式编写不当,可能导致性能瓶颈。
常见的性能问题:
-
回溯问题:正则表达式的回溯机制会尝试所有可能的匹配路径,导致执行时间显著增加。在处理不符合预期的输入时,回溯可能会导致性能严重下降。
优化策略:
- 尽量避免使用复杂的捕获组和多个
|
操作符,使用更简单的表达式。 - 使用
^
和$
等锚点来限制匹配的起始和结束位置,避免多次回溯。
- 尽量避免使用复杂的捕获组和多个
-
贪婪匹配问题:贪婪量词(如
*
、+
)会尽可能多地匹配字符,这在一些情况下可能导致不必要的长时间匹配。优化策略:
- 使用非贪婪量词(如
*?
、+?
)来尽量减少匹配的字符数量。 - 优化模式结构,避免过度匹配。
- 使用非贪婪量词(如
-
避免重复计算:某些正则表达式在匹配时可能需要重复计算相同的部分,导致不必要的性能消耗。
优化策略:
- 使用懒惰匹配来减少不必要的计算。
- 对于复杂的正则,考虑将表达式拆解成多个简单的部分,逐步进行匹配。
示例:
// 贪婪匹配的性能问题
String regex = "a.*b"; // 如果输入字符串中有多个'a'和'b',则可能导致多次回溯
String input = "aaaaaabbbbbbbbbb";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
System.out.println(matcher.find()); // 输出: true// 非贪婪匹配
String regexNonGreedy = "a.*?b"; // 使用非贪婪量词
matcher = Pattern.compile(regexNonGreedy).matcher(input);
System.out.println(matcher.find()); // 输出: true
在这个示例中,贪婪匹配会尝试匹配尽可能长的字符串,而非贪婪匹配会尽量少匹配字符,从而减少回溯。
14. 正则表达式的安全性
在某些情况下,恶意用户可能会构造特定的正则表达式,从而导致正则引擎出现拒绝服务(DoS)攻击。这种攻击通常被称为ReDoS(Regular Expression Denial of Service),其核心思想是通过让正则表达式执行大量的回溯操作,从而耗尽计算资源,导致服务崩溃。
ReDoS攻击的常见模式:
- 灾难性回溯:当正则表达式中包含大量的“贪婪”量词或者选择结构(
|
)时,输入数据的长度或结构会导致大量的回溯操作,从而消耗大量时间和计算资源。
防御策略:
- 避免复杂的贪婪量词:避免使用
.*
、.+
等可能导致回溯过多的模式,尤其是当用户输入数据不受控制时。 - 使用合适的正则引擎:某些现代正则引擎对这种类型的攻击具有内建的防御机制,例如使用回溯控制算法来限制回溯的次数。
示例:
// 容易被ReDoS攻击的正则
String regex = "(a+)+b"; // 这里存在潜在的回溯问题
String input = "a".repeat(10000) + "b"; // 大量'a'字符
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
System.out.println(matcher.matches()); // 可能会出现性能问题
防范ReDoS攻击的优化方式是尽量避免使用容易引发回溯问题的正则表达式,尤其是在用户输入未加验证的情况下。
15. 正则表达式的调试与工具使用
在开发中,调试正则表达式是一项非常重要的技能,尤其是当我们面对复杂的模式匹配时。幸运的是,许多工具和IDE插件都提供了调试支持。
调试技巧:
- 逐步测试:将正则表达式拆分成小部分,逐步测试每一部分的匹配情况。
- 可视化工具:使用在线正则表达式调试器(如regex101)来可视化和测试正则表达式。它们会显示每个部分的匹配过程,并指出可能存在的错误。
示例:
在正则调试器中输入正则"(\\d+)-(\\d+)"
和输入字符串"123-456"
, 工具会显示它如何逐步匹配数字并分组。通过这种可视化调试,我们能够清楚地看到正则表达式是如何工作的,从而避免常见的匹配错误。
16. 常见问题及解决方案
正则表达式在使用过程中经常会遇到一些常见问题,以下是几个常见的案例及解决方案。
-
问题 1:正则表达式中包含特殊字符怎么办?
- 解决方案:在正则表达式中需要匹配某些特殊字符(如
.
、*
、+
等)时,要使用反斜杠(\
)进行转义。 - 示例:
// 匹配字符串中的'.' String regex = "\\."; // 使用转义字符 String input = "Hello. World"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); System.out.println(matcher.find()); // 输出: true
- 解决方案:在正则表达式中需要匹配某些特殊字符(如
-
问题 2:如何匹配多种不同格式的日期?
- 解决方案:使用正则表达式匹配不同的日期格式。例如,可以设计一个表达式来匹配
yyyy-mm-dd
和mm/dd/yyyy
两种格式。 - 示例:
// 匹配yyyy-mm-dd格式和mm/dd/yyyy格式的日期 String regex = "(\\d{4})-(\\d{2})-(\\d{2})|(\\d{2})/(\\d{2})/(\\d{4})"; String input = "2022-10-15 or 10/15/2022"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); while (matcher.find()) {System.out.println(matcher.group()); // 输出: 2022-10-15, 10/15/2022 }
- 解决方案:使用正则表达式匹配不同的日期格式。例如,可以设计一个表达式来匹配
17. 正则表达式的调试与可视化
在开发过程中,正则表达式的调试往往是一个挑战,尤其是在正则表达式非常复杂的情况下。幸运的是,现在有许多工具可以帮助我们进行调试和可视化,使得正则的理解更加直观。
常用调试工具:
-
regex101:
regex101 是一个非常受欢迎的在线正则表达式调试工具,支持多种语言(包括 Java、Python、JavaScript 等)。该工具提供了实时的正则匹配结果展示,并且会详细说明正则表达式的每一部分如何进行匹配。 -
Regexr:
Regexr 是另一个强大的正则调试工具,它提供了实时匹配、正则构建帮助和常见正则表达式的示例。它对于初学者来说非常友好。
如何使用这些工具:
- 在工具中输入正则表达式和待匹配文本。
- 查看每一部分的匹配过程和正则语法的解释。
- 可以逐步调整正则表达式,并实时观察匹配结果,以便优化正则表达式。
例如,在 regex101
中,我们可以输入正则 (\d+)\s+(\w+)
和文本 "123 hello"
,它会实时显示匹配的部分,并分解每个分组。
18. 正则表达式与Unicode文本处理
正则表达式的强大之处之一就是它能够处理各种字符编码,包括 Unicode 编码。在多语言应用程序中,Unicode 已经成为了标准字符集,处理Unicode字符变得尤为重要。
处理 Unicode 编码的正则表达式:
- 正则表达式可以通过
\uXXXX
来匹配 Unicode 字符。例如,\u0041
匹配的是大写字母“A”。 - 在匹配中文字符时,我们可以使用
\p{InCJKUnifiedIdeographs}
来匹配所有汉字字符。
示例:
// 匹配所有中文字符
String regex = "\\p{IsHan}+";
String input = "我爱编程";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {System.out.println(matcher.group()); // 输出: 我爱编程
}// 匹配所有数字(包括Unicode中的数字)
String regexUnicode = "\\p{Nd}+"; // \p{Nd} 用于匹配所有数字
String inputUnicode = "12345 ١٢٣٤٥"; // 包含阿拉伯数字
Pattern patternUnicode = Pattern.compile(regexUnicode);
Matcher matcherUnicode = patternUnicode.matcher(inputUnicode);
while (matcherUnicode.find()) {System.out.println(matcherUnicode.group()); // 输出: 12345, ١٢٣٤٥
}
注意事项:
- 正则表达式中的Unicode处理能力非常强大,但是需要确保正则引擎支持Unicode,否则会出现匹配失败。
- 使用Unicode正则时,特别是针对多语言或特定地区的字符集时,需要特别注意正则表达式的兼容性和执行效率。
19. 正则表达式与多行匹配
在处理多行文本时,我们经常需要在行首和行尾进行匹配,这时使用正则表达式时需要特别小心。
多行匹配:
- 默认情况下,正则表达式使用的是单行模式,在这种模式下,
^
只能匹配文本的开始,$
只能匹配文本的结束。 - 使用
(?m)
模式(多行模式),可以让^
和$
匹配每一行的开始和结束,而不仅仅是整个文本的开始和结束。
示例:
String regex = "(?m)^\\d+";
String input = "123\n456\n789";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {System.out.println(matcher.group()); // 输出: 123, 456, 789
}
在上面的代码中,(?m)
启用了多行模式,^
匹配每行的开头,而不是整个文本的开头。
20. 常见的正则表达式流派及其特性
正则表达式的引擎存在不同的流派,它们在正则表达式的实现上有一定的差异。不同的正则引擎可能会有不同的性能特征、语法支持以及功能扩展。
常见的正则引擎流派:
- NFA(非确定性有限自动机):这种类型的正则引擎采用了回溯机制,常见的如 Python 的 re、JavaScript 的正则引擎等。
- DFA(确定性有限自动机):DFA 模式的正则引擎在执行时不依赖回溯,因此通常更高效。它适用于不涉及复杂回溯的匹配任务,如一些基于正则的搜索引擎。
- Thompson 构造算法:这种方法的正则引擎会将正则表达式转换为状态机并执行优化,Java 的
Pattern
类使用的正则引擎就采用了类似的策略。
优缺点:
- NFA:回溯机制使得它在复杂模式匹配时非常灵活,但在极端情况下性能较差,可能导致回溯过多。
- DFA:没有回溯机制,执行速度较快,但对于某些模式可能需要更多的内存。
- Thompson 算法:提供了一种比较高效的状态机生成方式,平衡了灵活性和性能。
21. 常见问题集锦:详解正则表达式常见问题及解决方案
-
问题 1:如何匹配不包含某个字符的字符串?
- 解决方案:可以使用负向前瞻(negative lookahead)来匹配不包含特定字符的字符串。
- 示例:
// 匹配不包含字母 'a' 的字符串 String regex = "^(?!.*a).*"; // 负向前瞻 String input = "Hello, World!"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); System.out.println(matcher.matches()); // 输出: true
-
问题 2:正则表达式中如何匹配换行符?
- 解决方案:换行符通常用
\n
或\r\n
来表示。 - 示例:
// 匹配换行符 String regex = "\\n"; String input = "Hello\nWorld"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); while (matcher.find()) {System.out.println("Found newline!"); // 输出: Found newline! }
- 解决方案:换行符通常用
-
问题 3:如何避免正则表达式中的重叠匹配?
- 解决方案:使用非捕获组(
(?:...)
)来避免不必要的匹配,同时使用非贪婪量词来避免重叠匹配。 - 示例:
// 避免重叠匹配 String regex = "(?:\\d+)"; String input = "123 456"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); while (matcher.find()) {System.out.println(matcher.group()); }
- 解决方案:使用非捕获组(
相关文章:
深入解析-正则表达式
学习正则,我们到底要学什么? 正则表达式(RegEx)是一种强大的文本匹配工具,广泛应用于数据验证、文本搜索、替换和解析等领域。学习正则表达式,我们不仅要掌握其语法规则,还需要学会如何高效地利…...
12306分流抢票软件 bypass v1.16.43 绿色版(春节自动抢票工具)
软件介绍 12306Bypass分流抢票软件,易操作强大的12306抢票软件,全程自动抢票,云识别验证码打码,多线程秒单、稳定捡漏,支持抢候补票、抢到票自动付款,支持多天、多车次、多席别、多乘客、短信提醒等功能。…...
Arduino UNO 驱动1.8 TFT屏幕显示中文
背景 最近入手了一块1.8寸的tft屏幕,通过学习文档,已经掌握了接线,显示英文、数字、矩形区域、划线、画点等操作, 但是想显示中文的时候操作比较复杂。 问题 1、arduino uno 驱动这款屏幕目前使的是自带的<TFT.h> 库操作…...
vue路由模式面试题
vue路由模式 1.路由的模式有哪些?有什么区别? history和hash模式 区别: 1.表现的形态不同: 在地址栏url中:hash模式中带有**#**号,history没有 2.请求错误时表现不同: 在hash模式中,对于404地址请求时,不会进行请求 但是在history模式中,对于404请求时,仍然会进行请求…...
计算机的错误计算(二百零一)
摘要 用两个大模型计算 ,结果保留 10位有效数字。实验表明,两个大模型的输出均只有1位正确数字;并它们几乎相同:仅最后1位数字不同。 例1. 计算 , 结果保留 10位有效数字。 下面是与一个数学解题器的对话。 以上为与一个数学解…...
WandB使用笔记
最近看代码,发现代码中有wandb有关的内容,搜索了一下发现是一个模型训练工具,然后学习了一下,这里记录一下使用过程,方便以后查阅。 WandB使用笔记 登录WandB 并 创建团队安装 WandB 并 登录模型训练过程跟踪模型版本管…...
TTL 传输中过期问题定位
问题: 工作环境中有一个acap的环境,ac的wan口ip是192.168.186.195/24,ac上lan上有vlan205,其ip子接口地址192.168.205.1/24,ac采用非nat模式,而是路由模式,在上级路由器上有192.168.205.0/24指向…...
spring mvc源码学习笔记之五
pom.xml 内容如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…...
Java 数据库连接 - Sqlite
Java 数据库连接 - Sqlite PS: 1. 连接依赖库:[sqlite-jdbc-xxx.jar](https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc)(根据连接的数据库版本选择) 2. 支持一次连接执行多次sql语句; 3. 仅本地连接;使用说明: publ…...
【Rust自学】10.2. 泛型
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 题外话:泛型的概念非常非常非常重要!!!整个第10章全都是Rust的重难点!…...
鸿蒙MPChart图表自定义(六)在图表中绘制游标
在鸿蒙开发中,MPChart 是一个非常强大的图表库,它可以帮助我们创建各种精美的图表。今天,我们将继续探索鸿蒙MPChart的自定义功能,重点介绍如何在图表中绘制游标。 OpenHarmony三方库中心仓 一、效果演示 以下是效果演示图&…...
PHP在做api开发中,RSA加密签名算法如何使用 ?
RSA 加密是什么 RSA(Rivest-Shamir-Adleman)是最早的公钥密码系统之一,广泛用于安全数据传输。3 位数学家 Rivest、Shamir 和 Adleman 的名字来命名的。 是非对称加密的一种 这种算法非常可靠,密钥越长,它就越难破解。…...
PHP+Redis的基本操作方法
一、Redis连接与认证 二、String操作 三、Hash操作 四、List操作 五、Set操作 六、Zset操作 一、Redis连接与认证 $redis new Redis(); //连接参数:ip、端口、连接超时时间,连接成功返回true,否则返回false $ret $redis->connec…...
非docker方式部署openwebui过程记录
之前一直用docker方式部署openwebui,结果这东西三天两头升级,我这一升级拉取docker镜像硬盘空间嗖嗖的占用,受不了,今天改成了直接部署,以下是部署过程记录。 一、停止及删除没用的docker镜像占用的硬盘空间 docker s…...
豆包ai 生成动态tree 增、删、改以及上移下移 html+jquery
[豆包ai 生成动态tree 增、删、改以及上移下移 htmljquery) 人工Ai 编程 推荐一Kimi https://kimi.moonshot.cn/ 推荐二 豆包https://www.doubao.com/ 实现效果图 html 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF…...
基于STM32环境温湿度监测系统设计(附项目代码zip)
一.介绍 本文详细介绍了一种基于STM32F103C8T6微控制器DS18B20温度传感器DHT11温湿度传感器的环境监测系统。该系统旨在实时监测周围环境的温度与湿度,通过OLED实时显示温湿度值,通过USART串口实时打印温湿度值,并在温湿度超过预设阈值时&am…...
Kafka配置公网或NLB访问(TCP代理)
这套配置适用于TCP代理和公网访问,kafka版本2.8,版本如果不同配置参数会有一些差异,原理一致 分几种场景,正常来说我们直接使用kafka IP地址访问就行,考虑到网络架构和环境安全,需要使用公网或代理访问kaf…...
30分钟学会css
CSS 基本语法 CSS(Cascading Style Sheets)是一种样式表语言,用于描述 HTML(或 XML)文档的呈现。它可以控制网页元素的颜色、字体、布局等外观样式,实现内容与表现的分离,让网页设计更加灵活和…...
若依修改超级管理员admin的密码
通过接口方式或者页面 /system/user/resetPwd 需改其他用户的密码 修改其他用户的加密的密码,然后通过数据库将admin更新为这个密码就修改好了...
《柴油遗产-无耻时代》V98375官方版
靠近你所在赛道上的另一名玩家进行攻击或防守,跳到另一条赛道上进行恢复,或闪到对手背后打他个措手不及。与队友合作,充分利用每个角色的独特玩法来控制战斗走向! 《柴油遗产-无耻时代》官方版 https://pan.xunlei.com/s/VODW7xDX…...
加固服务器有什么用?
为什么越来越多的企业和个人都在加固他们的服务器?加固服务器不仅可以保护数据安全,还能提升整体系统的稳定性和可靠性。下面是聚名网的一些介绍。 加固服务器的首要目的就是提高安全性。随着网络攻击手段的不断演变,黑客和恶意软件的威胁也…...
Json字符串解析失败
通过第三方服务,拿到响应体的data对象(拿到的时候对象是有值的) 通过JSON.parseObject方法,拿到的对象,值为null 通过查看对应的json字符串,发现命名不一样... JSONField SeriealizedName注解是用来解析j…...
比较 FreeSWITCH 的 asr 事件和回调函数
用 lua 来描述,是这样的 第一种做法: session:setVariable("fire_asr_events", "true") session:execute("detect_speech", "start-input-timers") 识别到结果之后可以收到 DETECTED_SPEECH 事件 另外一个做法…...
Pytorch 三小时极限入门教程
一、引言 在当今的人工智能领域,深度学习占据了举足轻重的地位。而 Pytorch 作为一款广受欢迎的深度学习框架,以其简洁、灵活的特性,吸引了大量开发者投身其中。无论是科研人员探索前沿的神经网络架构,还是工程师将深度学习技术落…...
125个Docker的常用命令
基本命令命令描述示例docker run创建并启动一个容器docker run -it ubuntu bashdocker ps列出当前运行的容器docker psdocker ps -a列出所有容器,包括未运行的docker ps -adocker stop停止一个运行中的容器docker stop [CONTAINER_ID]docker start启动一个已停止的容…...
C# 设计模式(结构型模式):组合模式
C# 设计模式(结构型模式):组合模式 在软件设计中,有时我们需要处理的是一组对象,而这些对象既可以是单独的元素,也可以是由多个子元素组成的复合体。这时,组合模式(Composite Patte…...
【HarmonyOS】:DevEco Studio安装与应用工程创建指南
前言 本文旨在为初涉 HarmonyOS 开发的开发者提供一份详尽的入门指南,涵盖从安装最新版 DevEco Studio 到使用该 IDE 创建首个应用工程的具体步骤。通过遵循本指南,您将能够顺利搭建起自己的开发环境,并迈出构建HarmonyOS应用的第一步。 一、…...
【C/C++】手搓项目中常用小工具:日志、sqlit数据库、Split切割、UUID唯一标识
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 绪论: 本章将写到一些手搓常用工具,方便在项目中的使用,并且在手搓的过程中一些函数如:日志 宏中的__VA_ARGS__接收可变参…...
【论文阅读】Anchor-based fast spectral ensemble clustering
论文地址:Anchor-based fast spectral ensemble clustering - ScienceDirect 代码地址: 摘要 集成聚类通过融合多个基础聚类方法,可以获得更好且更稳健的结果,因此受到广泛关注。尽管近年来已经出现了许多代表性的算法ÿ…...
asp.net core 发布到iis后,一直500.19,IIS设置没问题,安装了sdk,文件夹权限都有,还是报错
原因就是没有安装ASP.NET Core 9.0 Runtime (v9.0.0) - Windows Hosting Bundle,我是只安装了.net core的sdk,下面介绍下sdk和hosting bundle的关系 在 .NET Core 和 ASP.NET Core 的开发中,SDK(Software Development Kit&#x…...
牛客月赛108
目录 A. 小S按按钮 C. 小T数星星 E. 小M种树 A. 小S按按钮 (1) 二分答案的右边界一定要开大。若 x 等于 0,最多 2 * y 次 (2)根据是要最小还是最多,调整 if ( check ( mid ) ) 里的是 l 还是 r #include&l…...
QML自定义进度条和单选按钮的样式
1.自定义进度条的样式 1.1代码展示 import QtQuick 2.9 import QtQuick.Window 2.2 import QtQuick.Controls 2.1Window {visible: truewidth: 640height: 480title: qsTr("Hello World")ProgressBar {id: myProgressvalue: 0.5padding: 2anchors.centerIn: parent…...
jetbrain 安装 copilot
问题一:Sign in failed. Reason: Request signInInitiate failed with message: Request to /github.com/login/device/code> timed out after 30000ms, request id: 11, error code: -32603 解决方案: 参考资料:https://github.com/orgs/…...
FPGA 4x4矩阵键盘 实现
1原理 FPGA(现场可编程门阵列)4x4矩阵键盘的实现原理主要基于行列扫描法,通过FPGA对键盘的扫描和识别,实现对键盘输入信号的采集和处理。以下是对FPGA 4x4矩阵键盘实现原理的详细解释: 一、矩阵键盘的基本原理 结构:4x4矩阵键盘由4行和4列组成,共16个按键。每个按键位…...
探索 JMeter While Controller:循环测试的奇妙世界
嘿,宝子们!今天咱们就来聊聊 JMeter 里超级厉害的 While 控制器,它就像是一把神奇的钥匙,能帮我们打开循环测试的大门,模拟出各种各样复杂又有趣的场景哦! 一、While 控制器初印象 想象一下,你…...
Facebook元宇宙项目中的智能合约应用:提升虚拟空间的自治能力
近年来,Facebook在元宇宙领域的探索引起了广泛关注。元宇宙是一个融合虚拟现实(VR)、增强现实(AR)和互联网的沉浸式数字空间。在这个过程中,智能合约技术被认为是提升虚拟空间自治能力的关键工具。通过自动…...
前后端规约
文章目录 引言I 【强制】前后端交互的 API请求内容响应体响应码II 【推荐】MVC响应体III【参考】IV 其他引言 服务器内部重定向必须使用 forward;外部重定向地址必须使用 URL 统一代理模块生成,否则会因线上采用 HTTPS 协议而导致浏览器提示“不安全”,并且还会带来 URL 维护…...
获取 Astro Bot AI 语音来增强您的游戏体验!
有很多用户尝试过Astro Bot,却被Astro Bot可爱的声音所吸引。您是否想知道如何使用 Astro Bot 语音来拨打恶作剧电话或用他的声音说话?如果您有,那么这篇文章适合您。我们将向您展示如何为 Astro Bot 提供逼真的 AI 声音并在在线对话中使用它…...
javaEE-多线程进阶-JUC的常见类
juc:指的是java.util.concurrent包,该包中加载了一些有关的多线程有关的类。 目录 一、Callable接口 FutureTask类 参考代码: 二、ReentrantLock 可重入锁 ReentrantLock和synchronized的区别: 1.ReentantLock还有一个方法:…...
nginx配置 - 资源参数配置(性能优化)
nginx - 资源参数配置 (性能优化) 一、worker_rilimit_nofile配置的含义使用场景如何调整参数系统级文件描述符限制(补充)二、worker_connections三、两者之间的数值关系四、sendfile五、keepalive_timeout本文重点讨论: 最大文件描述符数量 worker_rilimit_nofile和最大连…...
TiDB 升级至高版本提示'mysql.tidb_runaway_watch' doesn't exist 问题处理
作者: asd80703406 原文来源: https://tidb.net/blog/90394c97 背景 近期发现很多人从低版本升级至TiDB v7 或者v8版本,均遇到了tidb-server启动失败,提示报错如下: ["get runaway watch record failed"…...
利用Deeplearning4j进行 图像识别
目录 图像识别简介 神经网络 感知器 前馈神经网络 自动编码器 受限玻尔兹曼机 深度卷积网络 理解图像内容以及图像含义方面,计算机遇到了很大困难。本章先介绍计算机理解图像教育方面 遇到的难题,接着重点讲解一个基于深度学习的解决方法。我们会…...
使用Python构建智能医疗诊断系统
医疗诊断系统在现代医疗领域中扮演着重要角色,尤其在辅助医生进行初步诊断、缩短诊断时间方面更是发挥了显著作用。借助Python强大的数据处理能力和机器学习工具,我们可以构建一个智能医疗诊断系统。本文将详细介绍实现过程,并结合代码示例帮助您理解。 引言 现代医学产生…...
NLP 技术的突破与未来:从词嵌入到 Transformer
在过去的十年中,自然语言处理(NLP)经历了深刻的技术变革。从早期的统计方法到深度学习的应用,再到如今Transformer架构的普及,NLP 的发展不仅提高了模型的性能,还扩展了其在不同领域中的应用边界。 1. 词嵌…...
【2024年-11月-9日-开源社区openEuler实践记录】OpenAMDC:开启智能边缘计算与系统管控的新征程
一、开篇:邂逅 OpenAMDC 大家好,我是 fzr123,在开源项目的浩瀚天地里持续探索,今天要带大家深入了解一项极具前瞻性与创新性的开源成果——OpenAMDC。在边缘计算蓬勃兴起、系统复杂度与日俱增的时代背景下,OpenAMDC 宛…...
ELK日志平台搭建 (最新版)
一、安装 JDK 1. 下载 JDK 21 RPM 包 wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.rpm2. 安装 JDK 21,使用 rpm 命令安装下载的 RPM 包: sudo rpm -ivh jdk-21_linux-x64_bin.rpm3. 配置环境变量 编辑 /etc/profile 文件以配置 JAVA_HO…...
蓝桥杯备赛:C++基础,顺序表和vector(STL)
目录 一.C基础 1.第一个C程序: 2.头文件: 3.cin和cout初识: 4.命名空间: 二.顺序表和vector(STL) 1.顺序表的基本操作: 2.封装静态顺序表: 3.动态顺序表--vector:…...
MySQL数据库——常见慢查询优化方式
本文详细介绍MySQL的慢查询相关概念,分析步骤及其优化方案等。 文章目录 什么是慢查询日志?慢查询日志的相关参数如何启用慢查询日志?方式一:修改配置文件方式二:通过命令动态启用 分析慢查询日志方式一:直…...
【NX入门篇】
NX入门篇 一、UG NX 由来二、软件如何启动(UG NX 12.0)三、使用步骤四、常用命令 一、UG NX 由来 UG NX由来: 1969 年:UG 的开发始于美国麦道航空公司,基于 C 语言开发实现;1976 年:UG问世&am…...
卡码网 ACM答题编程模板
背景: input() 在 ACM 编程中的底层调用原理 1. input() 的核心原理 在 Python 中,input() 的底层实现依赖于标准输入流 sys.stdin。每次调用 input() 时,Python 会从 sys.stdin 中读取一行字符串,直到遇到换行符 \n 或文件结束…...