JavaRush /Java 博客 /Random-ZH /Java 中正则表达式的基础知识。第三部分
articles
第 15 级

Java 中正则表达式的基础知识。第三部分

已在 Random-ZH 群组中发布
让我们继续研究正则表达式。在本文中,我们将研究预定义的字符类以及量化(搜索序列)。 Java 中正则表达式的基础知识。 第 3 - 1 部分

预定义字符类

类 APIPattern包含预定义的字符类,为常用的正则表达式提供方便的快捷方式。 Java 中正则表达式的基础知识。 第 3 - 2 部分在此表中,左列中的构造是右列中表达式的简写表示。例如,\d表示数字(0-9),\w表示任何大写或小写字母、下划线或数字)。尽可能使用预定义的字符类。这将使您的代码更易于阅读和修复错误。以反斜杠开头的结构称为转义或受保护。在之前的文章中,我们已经讨论过使用反斜杠或符号转义特殊字符\Q并将\E其用作常规字符。如果将反斜杠与常规字符(文字)一起使用,则需要转义反斜杠才能编译表达式。
private final String REGEX = "\\d"; // цифра
在这个例子中\d,一个正则表达式;程序编译需要额外的反斜杠。我们的测试程序直接从控制台读取正则表达式,因此不需要额外的斜杠。下面的示例演示了预定义字符类的使用: Java 中正则表达式的基础知识。 第 3 - 3 部分Java 中正则表达式的基础知识。 第 3 - 4 部分在前三个示例中,正则表达式只是“ .”(点特殊字符),表示任何字符。因此,在所有情况下搜索都是成功的。其他示例使用预定义的字符类,我们在上表中讨论了其含义。

量词

Java 中正则表达式的基础知识。 第 3 - 4 部分量词允许您指定字符在字符串中出现的次数。让我们仔细看看贪婪、惰性和非常贪婪量词如何工作的复杂性。乍一看,量词 X?, X?? 和 X?+ 的工作方式相同:“X 出现一次或根本不存在。” 这些量词的实现略有不同,我们将在下面讨论。

零长度匹配

让我们从贪婪的开始吧。让我们编写三个不同的正则表达式:带有特殊字符 ?、* 或 + 的字母“a”。让我们看看如果在空行上测试这些正则表达式会发生什么: Java 中正则表达式的基础知识。 第 3 - 5 部分在上面的示例中,前两种情况搜索成功,因为表达式 a? a* 允许字符串中缺少字符 a。另请注意,开始匹配索引和最后匹配索引相同 (0)。由于输入字符串没有长度,因此程序在第一个位置找不到任何内容:)。这种情况称为零长度匹配。此类匹配发生在多种情况下:当输入行为空时、在输入行的开头、在该行的最后一个字符之后或在该行的字符之间。零长度匹配很容易发现:它们在同一位置开始和结束。让我们看一些零长度匹配的更多示例。让我们通过更多示例来探讨零长度匹配。让我们将输入字符串更改为字符“a”并观察一个有趣的效果: Java 中正则表达式的基础知识。 第 3 - 6 部分所有三个量词都找到了字符“a”,但前两个量词(允许不存在字符)在位置 1 处找到了零长度匹配- 在字符串的最后一个字符之后。发生这种情况是因为程序将字符“a”视为字符串并“运行”它,直到不再有匹配项为止。根据所使用的量词,程序将或不会在字符串末尾找到“nothing”。现在让我们将输入字符串更改为五个字母“​​a”的序列: Java 中正则表达式的基础知识。 第 3 - 7 部分正则表达式 a?分别查找字符串中每个字母的匹配项。表达式 a* 找到两个匹配项:字符序列“a”'和位置 5 处的零长度匹配项。最后,正则表达式 a+ 只找到字符“a”的序列,而没有找到“nothing”:) 如果给出包含不同字符的字符串作为输入,会发生什么?例如,“ababaaaab”: Java 中正则表达式的基础知识。 第 3 - 8 部分字符“b”位于位置 1、3 和 8,并且程序在这些位置找到零长度匹配。正则表达式a? 不关注“b”,而只是查找字符“a”是否存在(或不存在)。如果量词允许不存在“a”,则字符串中除“a”之外的所有字符都将显示为零长度匹配。要查找给定长度的序列,只需在大括号中指定长度即可: Java 中正则表达式的基础知识。 第 3 - 9 部分正则表达式 a{3} 查找包含三个“a”字符的序列。第一行中没有找到任何内容,因为该行中没有足够的 a。第二个包含程序找到的 3 个字符。第三个测试还在字符串的开头找到匹配项。第三个字符之后的所有内容都不满足正则表达式,在下面的代码中它满足正则表达式,并且将有多个匹配项: Java 中正则表达式的基础知识。 第 3 - 10 部分要指定最小序列长度,请使用:
Enter your regex: a{3,}
Enter input string to search: aaaaaaaaa
I found the text "aaaaaaaaa" starting at index 0 and ending at index 9.
在此示例中,程序仅找到一个匹配项,因为该字符串满足 (3) 个“a”字符的最小序列长度要求。最后,设置最大序列长度: Java 中正则表达式的基础知识。 第 3 - 11 部分在本例中,第一个匹配在第六个字符处结束。第二个匹配包含第六个之后的字符,因为 它们满足最小长度要求。如果字符串短一个字符,则不会有第二个匹配项。

将字符组和类与量词一起使用

到目前为止,我们已经在包含相同字符的字符串上测试了量词。量词仅适用于单个字符,因此正则表达式“abc+”将匹配包含“ab”和“c”的字符串一次或多次。它不会表示“abc”一次或多次。但量词可以与组和字符类结合使用,例如 [abc]+(a 或 b 或 c,一次或多次)或 (abc)+(“abc”一次或多次)。让我们查找一组字符(狗),一行中出现三次: Java 中正则表达式的基础知识。 第 3 - 12 部分在第一个示例中,程序找到了一个匹配项,因为 量词扩展到一组字符。如果删除括号,量词 {3} 将仅适用于字母“g”。您还可以将量词与字符类一起使用: Основы регулярных выражений в Java. Часть 3 - 13{3} 量词适用于第一个示例中括号中的字符类,而在第二个示例中,仅适用于字符“c”。

贪婪量词、惰性量词和过度贪婪量词之间的区别

贪婪、不情愿和所有格量词之间存在细微差别。贪婪量词之所以如此命名,是因为它们试图找到最长的可能匹配:程序首先尝试“吃掉”整个字符串,如果未找到匹配,则丢弃一个字符并重复搜索,直到找到匹配或不再有角色了。另一方面,懒惰的人从行的开头开始,一个接一个地添加字符,直到找到匹配项。最后,嫉妒量化会扫描整个字符串一次,而不是像贪婪那样删除字符。为了进行演示,我们将使用字符串 xfooxxxxxxfoo。 Основы регулярных выражений в Java. Часть 3 - 14第一个示例使用贪婪的 .* 量词来查找任何字符(0 次或多次),后跟字符“f”“o”“o”。由于cantifier是贪婪的,所以找到的匹配包含整个字符串。贪婪量词不会找到字符串中的所有匹配项,因为 第一步,扫描整个字符串后,它将找到匹配项并完成工作。第二个示例是惰性的,从行的开头开始,逐个字符地添加。该程序首先检查“空”,但由于 序列“foo”不在行的开头,搜索将继续添加字符“x”,之后将在索引 0 和 4 之间找到第一个匹配项。搜索将继续,直到行尾第二个匹配将在索引 4 和 13 之间找到。第三个示例没有找到重合,因为量词是嫉妒的。在本例中,正则表达式 .*+ “吃掉”了整行,没有为“foo”留下任何内容。当您需要丢弃字符串中不需要的任何内容时,请使用嫉妒量词,它将比等效的贪婪量词更有效。就这样!源代码链接:Java 中正则表达式的基础知识。第三部分
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION