我正在阅读有关 Java 中的正则表达式的内容。据我了解,所有格量词不会回溯并释放角色,以便为其他组提供实现匹配的机会。 但我无法想象在现实中使用所有格量词的情况。 我读过一些资源,说由于所有格量词不会回溯,因此它们不需要记住输入字符串中每个字符的位置,这有助于显着提高正则表达式引擎的性能。 我已经通过编写示例对此进行了测试:
我有一个包含大约数千位数字的字符串。
首先我定义了一个贪婪:String regex = "(\d+)";
然后我数了一下所花费的时间。
第二:我更改为所有格:String regex = "(\d++)";
我也计算了所花费的时间,但我没有发现时间有任何差异
我是不是误解了什么?
此外,谁能给我一些使用所有格量词的具体案例?
关于这个术语:在《Java Regular Expressions Taming the Java.Util.Regex Engine by Mehran Habibi
》一书中,他使用了术语“所有格限定符
”,当我在互联网上阅读时,人们使用“所有格量词
”。哪一个是正确的还是两者都正确?
最佳答案
所有格量词是贪婪的量词(它们尝试匹配尽可能多的字符)并且不回溯(如果所有格量词走得太远,则可能匹配失败)。
示例
普通(贪婪)量词
假设您有以下正则表达式:
^([A-Za-z0-9]+)([A-Z0-9][A-Z0-9])(.*)
The regex aims to match "one or more alphanumerical-characters (case independent)
[A-Za-z0-9]
and should end with two alphanumerical characters and then any character can occur.
任何遵守此约束的字符串都将匹配。 AAA
也是如此。人们可以声称第二个和第三个 A
应该属于第二组,但这会导致字符串不匹配。因此,正则表达式具有智能(使用动态编程),知道何时离开(第一艘)船。
非贪婪量词
现在可能出现的一个问题是,第一组对于数据提取目的“过于贪婪”。假设您有以下字符串 AAAAAAA
。可以进行多种分割:(A)(AA)(AAAA)
、(AA)(AA)(AAA)
等。默认情况下,正则表达式中的每个组都是尽可能贪婪(只要这对字符串是否仍然匹配的事实没有影响)。因此,正则表达式将分割 (AAAAA)(AA)()
中的字符串。如果您想以这样的方式提取数据,即从传递一个字符的那一刻起,从出现 [A-Z0-9]
范围中的两个字符的那一刻起,正则表达式应移至下一组。
为了实现这一点,您可以编写:
^([A-Za-z0-9]+?)([A-Z0-9][A-Z0-9])(.*)
字符串AAAAAAA
将与(A)(AA)(AAAA)
匹配。
所有格量词
所有格量词是贪婪量词,但一旦可能,它们就永远不会将一个字符归还给另一个组。例如:
^([A-Z]++)([H-Zw])(.*)
如果您编写^([A-Z]+)([H-Z])(.*)
,则将匹配字符串AH0
。第一组是贪婪的(吃A
),但由于吃(这是有时使用的词)H
会导致字符串不匹配,所以愿意放弃H
。使用所有格量词。该团体也不愿意放弃H
。结果,它同时吃掉 A
和 H
。第二组只剩下0
,但第二组无法吃掉该角色。因此,正则表达式会失败,而使用非所有格量词会导致成功匹配。然而,字符串 Aw
将成功匹配,因为第一组对 w
不感兴趣...
关于java - Java 正则表达式中的所有格量词有何用途?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26006653/