Java正则表达式中的所有格量词用于什么?

Java正则表达式中的所有格量词用于什么?,java,regex,Java,Regex,我正在读Java中的正则表达式。而且我知道所有格量词不会回溯和释放字符来给其他组提供匹配的机会。 但我无法想象在现实中使用所有格量词的情况。 我已经阅读了一些参考资料,其中指出由于所有格量词不会回溯,它们不需要记住输入字符串中每个字符的位置,这有助于显著提高正则表达式引擎的性能。 我通过编写一个示例来测试这一点: 我有一个包含数千位数字的字符串 首先我定义了一个贪婪的:String regex=“(\d+” 然后我数了数所花的时间 第二:我改为所有格:String regex=“(\d++”)

我正在读Java中的正则表达式。而且我知道所有格量词不会回溯和释放字符来给其他组提供匹配的机会。 但我无法想象在现实中使用所有格量词的情况。 我已经阅读了一些参考资料,其中指出由于所有格量词不会回溯,它们不需要记住输入字符串中每个字符的位置,这有助于显著提高正则表达式引擎的性能。 我通过编写一个示例来测试这一点:

我有一个包含数千位数字的字符串

首先我定义了一个贪婪的:
String regex=“(\d+”

然后我数了数所花的时间

第二:我改为所有格:
String regex=“(\d++”)

我还计算了它花费的时间,但我看不出时间上有什么不同

我是不是误解了什么

此外,有谁能给我一些具体的例子,其中所有格量词在使用


关于这个术语:在Mehran Habibi的《Java正则表达式驯服Java.Util.Regex引擎》一书中,他使用了术语“
所有格限定词”
”,当我在互联网上阅读时,人们使用了“
所有格量词”
”。哪一个是正确的,还是两者都正确?

所有格量词是贪婪的量词(它们尝试匹配尽可能多的字符),并且不会回溯(如果所有格量词走得太远,匹配可能失败)

示例

正常(贪婪)量词

假设您有以下正则表达式:

^([A-Za-z0-9]+)([A-Z0-9][A-Z0-9])(.*)
正则表达式旨在匹配“一个或多个字母数字字符(独立于大小写)
[A-Za-z0-9]
,并应以两个字母数字字符结尾,然后可以出现任何字符

任何遵守此约束的字符串都将匹配。
AAA
也一样。可以声称第二个和第三个
A
应属于第二组,但这将导致字符串不匹配。因此正则表达式具有智能(使用动态编程)来知道何时离开(第一个)船

非贪婪量词

现在可能出现的一个问题是,第一个组对于数据提取而言“过于贪婪”。假设您有以下字符串
AAAAAAA
。可以进行几个细分:
(a)(AA)(AAAA)
(AA)(AA)(AAA)
,等等。默认情况下,正则表达式中的每个组都尽可能贪婪(只要这对字符串是否仍然匹配没有影响)。因此,正则表达式将在
(AAAAA)(AA)(
)中细分字符串。如果要以这种方式提取数据,则从传递一个字符开始,从
[a-Z0-9]中的两个字符开始
range出现时,正则表达式应移动到下一个组

为了实现这一点,您可以编写:

^([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
,但第二组不能吃该chaRacker。结果正则表达式失败,使用非所有格量词将导致成功匹配。但是字符串
Aw
将成功匹配,因为第一组对
w
不感兴趣。…

默认情况下,量词贪婪。它们将尝试尽可能多地匹配。所有格量词pr事件回溯,这意味着正则表达式匹配的内容将不会回溯到,即使这会导致整个匹配失败


所有格量词是防止正则表达式引擎 尝试所有排列。这主要对性能有用 原因。你也可以使用所有格量词来消除某些原因 火柴


一个好的@hwnd感谢你的链接。非常有用的“Quantifier”是正确的单词;它为任何应用它的东西都添加了数量方面的内容。Habibi的书充斥着草率的术语和明显的错误;我建议你扔掉它,改为阅读。它也非常好。@Alanmore:很遗憾,似乎没有勘误表页,等等。