让我们继续研究正则表达式。在本文中,我们将研究预定义的字符类以及量化(搜索序列)。
预定义字符类
类 APIPattern
包含预定义的字符类,为常用的正则表达式提供方便的快捷方式。 在此表中,左列中的构造是右列中表达式的简写表示。例如,\d
表示数字(0-9),\w
表示任何大写或小写字母、下划线或数字)。尽可能使用预定义的字符类。这将使您的代码更易于阅读和修复错误。以反斜杠开头的结构称为转义或受保护。在之前的文章中,我们已经讨论过使用反斜杠或符号转义特殊字符\Q
并将\E
其用作常规字符。如果将反斜杠与常规字符(文字)一起使用,则需要转义反斜杠才能编译表达式。
private final String REGEX = "\\d"; // цифра
在这个例子中\d
,一个正则表达式;程序编译需要额外的反斜杠。我们的测试程序直接从控制台读取正则表达式,因此不需要额外的斜杠。下面的示例演示了预定义字符类的使用: 在前三个示例中,正则表达式只是“ .
”(点特殊字符),表示任何字符。因此,在所有情况下搜索都是成功的。其他示例使用预定义的字符类,我们在上表中讨论了其含义。
量词
量词允许您指定字符在字符串中出现的次数。让我们仔细看看贪婪、惰性和非常贪婪量词如何工作的复杂性。乍一看,量词 X?, X?? 和 X?+ 的工作方式相同:“X 出现一次或根本不存在。” 这些量词的实现略有不同,我们将在下面讨论。零长度匹配
让我们从贪婪的开始吧。让我们编写三个不同的正则表达式:带有特殊字符 ?、* 或 + 的字母“a”。让我们看看如果在空行上测试这些正则表达式会发生什么: 在上面的示例中,前两种情况搜索成功,因为表达式 a? a* 允许字符串中缺少字符 a。另请注意,开始匹配索引和最后匹配索引相同 (0)。由于输入字符串没有长度,因此程序在第一个位置找不到任何内容:)。这种情况称为零长度匹配。此类匹配发生在多种情况下:当输入行为空时、在输入行的开头、在该行的最后一个字符之后或在该行的字符之间。零长度匹配很容易发现:它们在同一位置开始和结束。让我们看一些零长度匹配的更多示例。让我们通过更多示例来探讨零长度匹配。让我们将输入字符串更改为字符“a”并观察一个有趣的效果: 所有三个量词都找到了字符“a”,但前两个量词(允许不存在字符)在位置 1 处找到了零长度匹配- 在字符串的最后一个字符之后。发生这种情况是因为程序将字符“a”视为字符串并“运行”它,直到不再有匹配项为止。根据所使用的量词,程序将或不会在字符串末尾找到“nothing”。现在让我们将输入字符串更改为五个字母“a”的序列: 正则表达式 a?分别查找字符串中每个字母的匹配项。表达式 a* 找到两个匹配项:字符序列“a”'和位置 5 处的零长度匹配项。最后,正则表达式 a+ 只找到字符“a”的序列,而没有找到“nothing”:) 如果给出包含不同字符的字符串作为输入,会发生什么?例如,“ababaaaab”: 字符“b”位于位置 1、3 和 8,并且程序在这些位置找到零长度匹配。正则表达式a? 不关注“b”,而只是查找字符“a”是否存在(或不存在)。如果量词允许不存在“a”,则字符串中除“a”之外的所有字符都将显示为零长度匹配。要查找给定长度的序列,只需在大括号中指定长度即可: 正则表达式 a{3} 查找包含三个“a”字符的序列。第一行中没有找到任何内容,因为该行中没有足够的 a。第二个包含程序找到的 3 个字符。第三个测试还在字符串的开头找到匹配项。第三个字符之后的所有内容都不满足正则表达式,在下面的代码中它满足正则表达式,并且将有多个匹配项: 要指定最小序列长度,请使用: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”字符的最小序列长度要求。最后,设置最大序列长度: 在本例中,第一个匹配在第六个字符处结束。第二个匹配包含第六个之后的字符,因为 它们满足最小长度要求。如果字符串短一个字符,则不会有第二个匹配项。
GO TO FULL VERSION