【JavaWeb】正则表达式

news2024/11/15 16:37:26

🎄欢迎来到@边境矢梦°的csdn博文,本文主要讲解Java 中正则表达式 的相关知识🎄


🌈我是边境矢梦°,一个正在为秋招和算法竞赛做准备的学生🌈
🎆喜欢的朋友可以关注一下🫰🫰🫰,下次更新不迷路🎆

Ps: 月亮越亮说明知识点越重要 (重要性或者难度越大)🌑🌒🌓🌔🌕 

目录

🌓一. 问题的引出

🌓二. 解决问题

🌒三. 正则表达式的好处

🌕四. 正则表达式语法

🌔1.限定符

🌔 2.选择匹配符

🌕3.分组组合和反向引用符

🌕4. 特殊字符

🌕5.字符匹配符

🌔6.定位符

🌔五. 修饰符

🌔六. 运算符优先级

🌔七. 元字符


现实中, 检索是非常常见的,为了加快检索速度, 引出了正则表达式, 正则表达式是一种强大的文本模式匹配工具,可以用来搜索、识别和提取文本中的特定模式.一个正则表达式,就是用某种模式去匹配字符串的一个公式。很多人因为它们看上去比较古怪而且复杂所以不敢去使用,不过,经过练习后,就觉得这些复杂的表达式写起来还是相当简单的,而且,一旦你弄懂它们,你就能把数小时辛苦而且易错的文本处理工作缩短在几分钟(甚至几秒钟)内完成.

一. 问题的引出

当不使用正则表达式时,以下示例说明可能会遇到的缺点:

  • 代码复杂度提高:
// 字符串验证(电子邮件地址)
String email = "test@example.com";

if (email.contains("@")) {
    String[] parts = email.split("@");
    if (parts.length == 2) {
        String domain = parts[1];
        if (domain.contains(".") && domain.length() > 2) {
            System.out.println("Valid email address");
        }
    }
}

相比使用正则表达式,上述代码需要多个条件判断和字符串操作来验证电子邮件地址的合法性,使得代码变得冗长且可读性较差。

  • 可读性降低:
// 提取文本中的所有日期(格式为YYYY-MM-DD)
String text = "Today is 2023-07-28. Tomorrow will be 2023-07-29. Next week is 2023-08-04.";

String[] words = text.split(" ");
for (String word : words) {
    if (word.length() == 10) {
        String[] dateParts = word.split("-");
        if (dateParts.length == 3 && dateParts[0].length() == 4 && dateParts[1].length() == 2 && dateParts[2].length() == 2) {
            try {
                int year = Integer.parseInt(dateParts[0]);
                int month = Integer.parseInt(dateParts[1]);
                int day = Integer.parseInt(dateParts[2]);
                if (year >= 1900 && year <= 2099 && month >= 1 && month <= 12 && day >= 1 && day <= 31) {
                    System.out.println(word);
                }
            } catch (NumberFormatException e) {
                // Ignore invalid dates
            }
        }
    }
}

上述代码在提取文本中的日期时,需要多个条件判断和字符串操作,使得代码变得晦涩难懂,对于日期格式的要求也不易于理解。

  • 匹配和处理效率低:
    如果需要从一段文本中获取所有以字母 “a” 开头的单词,而不使用正则表达式,可能需要编写如下的代码:
String text = "apple is a fruit, and it tastes amazing. An animal starts with aardvark.";

String[] words = text.split(" ");
for (String word : words) {
    if (word.toLowerCase().startsWith("a")) {
        System.out.println(word);
    }
}

由于需要对每一个单词进行字符串操作和条件判断,代码的效率较低,尤其是在处理大量文本时可能会造成性能问题。

  • 处理复杂模式困难:
    如果需要从 HTML 文档中提取所有的超链接文本和 URL,而不使用正则表达式,可能需要编写复杂的代码来处理各种标签和属性:
String html = "<a href=\"https://www.example.com\">Example</a> website. <a href=\"https://www.google.com\">Google</a> search engine.";

int startIndex = html.indexOf("<a");
while (startIndex != -1) {
    int endIndex = html.indexOf("</a>", startIndex);
    if (endIndex != -1) {
        String link = html.substring(startIndex, endIndex);

        int urlStartIndex = link.indexOf("href=\"");
        if (urlStartIndex != -1) {
            urlStartIndex += 6;
            int urlEndIndex = link.indexOf("\"", urlStartIndex);
            if (urlEndIndex != -1) {
                String url = link.substring(urlStartIndex, urlEndIndex);

                int textStartIndex = link.indexOf(">", urlEndIndex);
                if (textStartIndex != -1) {
                    textStartIndex += 1;
                    String text = link.substring(textStartIndex);
                    System.out.println("URL: " + url + ", Text: " + text);
                }
            }
        }
    }

    startIndex = html.indexOf("<a", startIndex + 1);
}

上述代码需要进行多次的字符串搜索和子字符串提取,处理起来较为繁琐和不直观。

通过上述示例可以看出,在处理字符串匹配和操作时,不使用正则表达式可能会导致代码复杂度提高、可读性降低、匹配和处理效率降低、处理复杂模式困难等问题。因此,正则表达式的简洁和强大的语法规则可以帮助我们更轻松地处理这些任务,提高代码的效率和可读性。


二. 解决问题

当使用正则表达式来解决前述提到的缺点时,可以得到以下示例:

  • 代码复杂度提高:
// 字符串验证(电子邮件地址)
String email = "test@example.com";
String pattern = "^[a-zA-Z0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z]{2,})+$";

if (email.matches(pattern)) {
    System.out.println("Valid email address");
}

通过使用正则表达式,可以将复杂的验证逻辑简化为一行代码,使代码更加简洁和易读。

  • 可读性降低:
// 提取文本中的所有日期(格式为YYYY-MM-DD)
String text = "Today is 2023-07-28. Tomorrow will be 2023-07-29. Next week is 2023-08-04.";
String pattern = "\\d{4}-\\d{2}-\\d{2}";

Pattern regex = Pattern.compile(pattern);
Matcher matcher = regex.matcher(text);

while (matcher.find()) {
    String date = matcher.group();
    System.out.println(date);
}

使用正则表达式提取日期时,通过使用简洁明了的正则表达式模式,可以更清晰地表达我们所需的日期格式要求。

  • 匹配和处理效率低:
// 获取所有以字母 "a" 开头的单词
String text = "apple is a fruit, and it tastes amazing. An animal starts with aardvark.";
String pattern = "\\ba\\w*\\b";

Pattern regex = Pattern.compile(pattern);
Matcher matcher = regex.matcher(text);

while (matcher.find()) {
    String word = matcher.group();
    System.out.println(word);
}

通过使用正则表达式,可以利用其内部的优化算法,提高匹配和处理效率,避免了对每个单词进行字符串操作和条件判断的情况。

  • 处理复杂模式困难:
// 从 HTML 文档中提取超链接文本和 URL
String html = "<a href=\"https://www.example.com\">Example</a> website. <a href=\"https://www.google.com\">Google</a> search engine.";
String pattern = "<a\\s+href=\"([^\"]+)\"[^>]*>(.*?)</a>";

Pattern regex = Pattern.compile(pattern);
Matcher matcher = regex.matcher(html);

while (matcher.find()) {
    String url = matcher.group(1);
    String text = matcher.group(2);
    System.out.println("URL: " + url + ", Text: " + text);
}

通过使用正则表达式,可以有效地处理复杂的模式,一次性提取出超链接的文本和 URL,不需要手动解析和提取标签和属性。

通过上述示例,使用正则表达式可以简化代码,提高可读性,并提供更高效和简洁的解决方案来处理字符串的匹配和操作。


三. 正则表达式的好处

学习正则表达式的好处有以下几个方面:

  1. 文本匹配和搜索:正则表达式是一种强大的文本模式匹配工具,可以用来搜索、识别和提取文本中的特定模式。通过学习正则表达式,可以更高效地处理文本数据,实现自动化的文本处理和分析。

  2. 数据验证和过滤:正则表达式广泛用于验证和过滤输入数据。可以利用正则表达式定义特定的模式要求,对用户输入的数据进行合法性验证,防止恶意输入和代码注入等安全问题。

  3. 字符串操作和替换:正则表达式提供了强大的字符串操作功能,可以实现字符串的查找、替换、切割等操作。通过学习正则表达式,可以编写灵活且高效的字符串处理代码,提高开发效率。

  4. 数据提取和分析:当处理非结构化的文本数据时,正则表达式可以帮助从中提取出所需信息。例如,从日志文件中提取出特定格式的日志记录,从 HTML 文档中提取出特定标签的内容等。学习正则表达式可以使数据提取和分析更加便捷和准确。

  5. 编程语言和工具支持:正则表达式是许多编程语言和工具的一部分,包括Java、JavaScript、Python、Perl等。学习正则表达式可以使得在编程中能够更好地利用和应用正则表达式,实现更高级的文本处理功能。

总体来说,学习正则表达式可以提升文本处理和数据操作的能力,减少重复工作,简化代码逻辑,并且广泛应用于软件开发、数据分析、文本处理等领域。无论是在后端开发、数据科学还是网络安全等领域,掌握正则表达式都是一项有价值的技能。


四. 正则表达式语法

1.限定符

字符描述
*匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于 {0,}。
+匹配前面的子表达式一次或多次。例如,zo+ 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
?

匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 "do" 、 "does"、 "doxy" 中的 "do" 和 "does"。? 等价于 {0,1}。

{n}n 是一个非负整数。匹配确定的 n 次。例如,o{2} 不能匹配 "Bob" 中的 o,但是能匹配 "food" 中的两个 o
{n,}n 是一个非负整数。至少匹配n 次。例如,o{2,} 不能匹配 "Bob" 中的 o,但能匹配 "foooood" 中的所有 o。o{1,} 等价于 o+。o{0,} 则等价于 o*。
{n,m}m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 "fooooood" 中的前三个 o。o{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。

 

 2.选择匹配符

|指明两项之间的一个选择。要匹配 |,请使用 \|。

3.分组组合和反向引用符

分组由圆括号 () 定义,在其中可以放置一个子表达式或多个模式。这些模式可以按照所需的方式组合在一起。

反向引用符 \ 后跟分组的编号用于引用先前匹配的子字符串。分组的编号从左到右,从 1 开始。

var str = "apple apple banana";

// 匹配两个相同的单词
var pattern1 = /(\w+) \1/;
console.log(str.match(pattern1));
// 输出: ["apple apple", "apple"]

// 匹配连续出现的相同字符
var pattern2 = /(\w)\1+/g;
console.log(str.match(pattern2));
// 输出: ["pp", "pp", "n"]

// 匹配重复出现的单词
var pattern3 = /\b(\w+)\b\s+\1\b/g;
console.log(str.match(pattern3));
// 输出: ["apple apple"]

在上述示例中:

  • (\w+) 是第一个分组,匹配一个或多个连续的单词字符。
  • \1 是对第一个分组的反向引用,确保第一个分组中的内容在字符串中再次出现。
  • (\w)\1+ 匹配连续出现的相同字符,例如 “pp” 和 “n”。
  • \b(\w+)\b\s+\1\b 匹配重复出现的单词,在单词之间可能有空白字符。\b 是单词边界,\s+ 匹配一个或多个空白字符。

分组组合和反向引用可以提供更高级的模式匹配和处理能力,尤其在需要匹配重复出现的内容或需要引用先前匹配的内容时非常有用。但请注意,不同的编程语言和工具在处理反向引用时可能有细微差异,因此要确保在特定环境中正确使用它们。

4. 特殊字符

特别字符描述
$匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。
( )标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。
*匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
+匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
.匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
[标记一个中括号表达式的开始。要匹配 [,请使用 \[。
?匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
\将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。
^匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^。
{标记限定符表达式的开始。要匹配 {,请使用 \{。
|指明两项之间的一个选择。要匹配 |,请使用 \|。

5.字符匹配符

  1. \d:匹配一个数字字符。等效于 [0-9]
  2. \D:匹配一个非数字字符。等效于 [^0-9]
  3. \w:匹配一个单词字符(字母、数字、下划线)。等效于 [A-Za-z0-9_]
  4. \W:匹配一个非单词字符。等效于 [^A-Za-z0-9_]
  5. \s:匹配一个空白字符(空格、制表符、换行符等)。等效于 [\t\n\r\f\v]
  6. \S:匹配一个非空白字符。等效于 [^\t\n\r\f\v]
  7. .:匹配除换行符以外的任意字符。
  8. [ ]:字符类,匹配括号内的任意一个字符。
  9. [^ ]:否定字符类,匹配除了括号内的字符以外的任意字符。
var str = "123 abc $%^";

// 匹配一个数字字符
var pattern1 = /\d/;
console.log(str.match(pattern1));
// 输出: ["1"]

// 匹配一个非数字字符
var pattern2 = /\D/;
console.log(str.match(pattern2));
// 输出: [" "]

// 匹配一个单词字符
var pattern3 = /\w/;
console.log(str.match(pattern3));
// 输出: ["1"]

// 匹配一个非单词字符
var pattern4 = /\W/;
console.log(str.match(pattern4));
// 输出: [" "]

// 匹配一个空白字符
var pattern5 = /\s/;
console.log(str.match(pattern5));
// 输出: [" "]

// 匹配一个非空白字符
var pattern6 = /\S/;
console.log(str.match(pattern6));
// 输出: ["1"]

// 匹配除换行符以外的任意字符
var pattern7 = /./g;
console.log(str.match(pattern7));
// 输出: ["1", "2", "3", " ", "a", "b", "c", " ", "$", "%", "^"]

// 匹配 "a"、"b" 或 "c"
var pattern8 = /[abc]/;
console.log(str.match(pattern8));
// 输出: ["a"]

// 匹配非数字和非字母的任意字符
var pattern9 = /[^a-zA-Z0-9]/g;
console.log(str.match(pattern9));
// 输出: [" ", " ", "$", "%", "^"]

6.定位符

字符描述
^匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 \n 或 \r 之后的位置匹配。
$匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。
\b匹配一个单词边界,即字与空格间的位置。
\B非单词边界匹配。

五. 修饰符

标记也称为修饰符,正则表达式的标记用于指定额外的匹配策略。

标记不写在正则表达式里,标记位于表达式之外,格式如下:

/pattern/flags

以下是一些常见的正则表达式修饰符:

  1. i:忽略大小写。添加 i 修饰符后,正则表达式匹配将不区分大小写。
  2. g:全局匹配。添加 g 修饰符后,正则表达式将会匹配字符串中所有的匹配项,而不仅仅是第一个。
  3. m:多行匹配。添加 m 修饰符后,正则表达式将会跨越多行进行匹配,而不仅仅是单行。
  4. s:单行匹配。添加 s 修饰符后,. 元字符将匹配包括换行符在内的任何字符。
  5. u:Unicode 匹配。添加 u 修饰符后,正则表达式将使用 Unicode 模式进行匹配。

修饰符通常被放置在正则表达式的斜杠 / 后面。

以下是使用正则表达式修饰符的一些示例:

var str = "Hello world!";

// 使用 "i" 修饰符忽略大小写
var pattern1 = /hello/i;
console.log(pattern1.test(str));
// 输出: true

// 使用 "g" 修饰符全局匹配
var pattern2 = /o/g;
console.log(str.match(pattern2));
// 输出: ["o", "o"]

// 使用 "m" 修饰符多行匹配
var pattern3 = /^w/m;
console.log(str.match(pattern3));
// 输出: ["w"]

// 使用 "s" 修饰符单行匹配
var pattern4 = /o.s/;
console.log(str.match(pattern4));
// 输出: ["orld"]

// 使用 "u" 修饰符 Unicode 匹配
var pattern5 = /\u{1F600}/u;
console.log(pattern5.test(str));
// 输出: false

 请注意,修饰符在不同的编程语言和工具中可能略有不同


六. 运算符优先级

运算符描述
\转义符
(), (?:), (?=), []圆括号和方括号
*, +, ?, {n}, {n,}, {n,m}限定符
^, $, \任何元字符、任何字符定位点和序列(即:位置和顺序)
|替换,"或"操作
字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。

 


七. 元字符

字符描述
\

将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。

^

匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。

$

匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。

*

匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。

+

匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。

?

匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 。? 等价于 {0,1}。

{n}

n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。

{n,}

n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。

{n,m}

m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。

?

当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。

.

匹配除换行符(\n、\r)之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用像"(.|\n)"的模式。

(pattern)

匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 '\(' 或 '\)'。

(?:pattern)

匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。

(?=pattern)

正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

(?!pattern)

正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如"Windows(?!95|98|NT|2000)"能匹配"Windows3.1"中的"Windows",但不能匹配"Windows2000"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

(?<=pattern)反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,"(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。
(?<!pattern)反向否定预查,与正向否定预查类似,只是方向相反。例如"(?<!95|98|NT|2000)Windows"能匹配"3.1Windows"中的"Windows",但不能匹配"2000Windows"中的"Windows"。
x|y

匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。

[xyz]

字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。

[^xyz]

负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'、'l'、'i'、'n'。

[a-z]

字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。

[^a-z]

负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。

\b

匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。

\B

匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。

\cx

匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。

\d

匹配一个数字字符。等价于 [0-9]。

\D

匹配一个非数字字符。等价于 [^0-9]。

\f

匹配一个换页符。等价于 \x0c 和 \cL。

\n

匹配一个换行符。等价于 \x0a 和 \cJ。

\r

匹配一个回车符。等价于 \x0d 和 \cM。

\s

匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。

\S

匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。

\t

匹配一个制表符。等价于 \x09 和 \cI。

\v

匹配一个垂直制表符。等价于 \x0b 和 \cK。

\w

匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。

\W

匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。

\xn

匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' & "1"。正则表达式中可以使用 ASCII 编码。

\num

匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)\1' 匹配两个连续的相同字符。

\n

标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。

\nm

标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。

\nml

如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。

\un

匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。

正则表达式 – 教程 | 菜鸟教程 (runoob.com) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/805307.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Metabase RCE漏洞复现(CVE-2023-38646)

0x01 产品简介 Metabase是一个开源的数据分析和可视化工具&#xff0c;它可以帮助用户轻松地连接到各种数据源&#xff0c;包括数据库、云服务和API&#xff0c;然后使用直观的界面进行数据查询、分析和可视化。 0x02 漏洞概述 未经身份认证的远程攻击者利用该漏洞可以在服务器…

【C语言趣味教程】(4) 变量:代码注释 | 变量的声明 | 初始化与赋值 | 变量的命名 | 关键字 | 标识符 | 变量名的命名规范

&#x1f517; 《C语言趣味教程》&#x1f448; 猛戳订阅&#xff01;&#xff01;&#xff01; Ⅰ. 代码注释&#xff08;Comment&#xff09; 0x00 引入&#xff1a;注释的作用 "程序员最讨厌两种人&#xff1a;一种是不写注释的人&#xff0c;一种是让我写注释的人。…

如何用DHTMLX组件为Web应用创建甘特图?(一)

dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的所有需求&#xff0c;是最完善的甘特图图表库。甘特图仍然是项目管理应用程序中最需要的工具之一&#xff0c;DHTMLX Gantt组件提供了能提升研发甘特图功能所需的重要工具。 在这篇…

【深度学习】InST,Inversion-Based Style Transfer with Diffusion Models,论文

代码&#xff1a;https://github.com/zyxElsa/InST 论文&#xff1a;https://arxiv.org/abs/2211.13203 文章目录 AbstractIntroductionRelated WorkImage style transferText-to-image synthesisInversion of diffusion models MethodOverview ExperimentsComparison with Sty…

我的第一个后端项目(环境搭建,Springboot项目,运行,接口验证)

一. 安装Java开发工具包&#xff08;JDK&#xff09;&#xff1a; 访问Java Software | OracleOracle官方网站&#xff0c;下载适合你操作系统的最新版本的JDK。安装JDK并设置好JAVA_HOME环境变量。 二. 安装集成开发环境&#xff08;IDE&#xff09;&#xff1a; 推荐使用In…

Appium+python自动化(二十八)- 高级滑动(超详解)

高级溜冰的滑动 滑动操作一般是两点之间的滑动&#xff0c;这种滑动在这里称其为低级的溜冰滑动&#xff1b;就是上一节给小伙伴们分享的。然而实际使用过程中用户可能要进行一些多点连续滑动操作。如九宫格滑动操作&#xff0c;连续拖动图片移动等场景。那么这种高级绚丽的溜…

word里的页码问题

一份文档写完&#xff0c;如果需要页码&#xff0c;第一页是封面&#xff0c;封面不需要页码怎么办&#xff1f; 解决&#xff1a;打开页眉页脚&#xff0c;然后把首页不同勾选上&#xff0c;这一页就没有页码了。 目录页&#xff0c;往往要使用罗马数字&#xff0c;其他正文又…

《遗留系统现代化》读书笔记(模式篇-代码现代化(一))

本文地址&#xff1a;http://t.csdn.cn/vS0Za 文章目录 代码现代化&#xff1a;你的代码可测吗&#xff1f;你的代码可测吗&#xff1f;标题如何让代码变得可测&#xff1f;接缝的位置接缝的类型新生和外覆为代码添加测试决策表模式测试的类型和组织遗留系统中的测试策略 代码…

【深度学习笔记】Softmax 回归

本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记&#xff0c;视频由网易云课堂与 deeplearning.ai 联合出品&#xff0c;主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习&#xff0c;视频的链接如下&#xff1a; 神经网络和…

QuantMania!《快乐机器学习》和《Python 从入门到入迷》作者,FRM,CAIA

王的机器主理人 王圣元 (FRM, CAIA) 某加密货币公司 Head of Quant 冬海集团 SeaMoney 建模负责人 八方咨询 量化总监 新加坡国立大学金融数学硕士 新加坡国立大学量化金融学士 《快乐机器学习》的作者 《Python 从入门到入迷》的作者 第一本书 《快乐机器学习》 第二本书《Pyt…

MySQL 8.0详细安装配置教程

一. 前言 MySQL是目前最为流行的开源数据库产品&#xff0c;是完全网络化跨平台的关系型数据库系统。它起初是由瑞典MySQLAB公司开发&#xff0c;后来被Oracle公司收购&#xff0c;目前属于Oracle公司。因为开源&#xff0c;所以任何人都能从官网免费下载MySQL软件&#xff0c…

【4】-多个User执行测试

目录 一个locustfile中有多个User 使用--class-picker指定执行 小结 一个locustfile中有多个User from locust import task, HttpUserclass User01(HttpUser):weight 3 # 权重host https://www.baidu.comtaskdef user_01_task(self):self.client.get(url/, nameuser_01_…

echarts柱状图每根柱子添加警戒值/阈值,分段警戒线

需求&#xff1a;柱状图每根柱子都添加单独的警戒值&#xff08;黄色线部分&#xff09;&#xff0c;效果图如下&#xff1a; 实现方式我这有两种方案&#xff0c;如下介绍。 方案1&#xff1a;使用echarts的标线markLine实现&#xff08;ps&#xff1a;此种方案有弊端&#x…

小程序通过ip+port+路径获取服务器中的图片

配置IIS 首先需要配置IIS。 打开控制面板&#xff0c;接下来的流程按下图所示。 安装好后&#xff0c;按“win”键&#xff0c;搜索IIS 选择一个ip地址&#xff0c;或手动填写&#xff0c;端口号按需更改 填写别名和物理路径&#xff0c;别名就是后续通过url访问物理…

初步了解预训练语言模型BERT

本文字数&#xff1a;&#xff1a;4024字 预计阅读时间&#xff1a;12分钟 BERT是由Google提出的预训练语言模型&#xff0c;它基于transformer架构&#xff0c;被广泛应用于自然语言处理领域&#xff0c;是当前自然语言处理领域最流行的预训练模型之一。而了解BERT需要先了解注…

Mock-MOCO使用过程

一、jar包下载&#xff1a;https://github.com/dreamhead/moco 二、准备mock的json文件 data.json内容&#xff1a; ####GET请求 [{"description": "response使用Content-Type为charsetGBK编码格式来查看返回信息为中文的内容","request": {&q…

LeetCode101. 对称二叉树

101. 对称二叉树 一、题目 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false提示&am…

一百三十七、Hive——HQL运行报错(持续更新中)

一、timestamp字段与int字段相加 &#xff08;一&#xff09;场景 change_time字段是timestamp字段&#xff0c;代表一个红绿灯周期的开始时间&#xff08;先是绿灯、再是黄灯、最后红灯&#xff09;&#xff0c;而green是int字段&#xff0c;代表绿灯的秒数&#xff0c;现在…

Linux常用基础命令-------你想要的我都有❀

文章目录❀ ❀ls命令 ❀cd命令 ❀pwd命令 ❀date命令 ❀创建、删除文件和目录命令 ❀alias命令 ❀复制、移动、重命名、查看&#xff08;文件、目录&#xff09;命令 ❀find查找、wc统计命令 ❀vi/vim命令 1、打开文件 2、工作模式 vi与vim的四个模式 进入编辑模式…

Verilog语法学习——LV2_异步复位的串联T触发器

LV2_异步复位的串联T触发器 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 题目描述&#xff1a; 用verilog实现两个串联的异步复位的T触发器的逻辑&#x…