java - Java 正则表达式中的所有格量词有何用途?

标签 java regex

我正在阅读有关 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。结果,它同时吃掉 AH。第二组只剩下0,但第二组无法吃掉该角色。因此,正则表达式会失败,而使用非所有格量词会导致成功匹配。然而,字符串 Aw 将成功匹配,因为第一组对 w 不感兴趣...

关于java - Java 正则表达式中的所有格量词有何用途?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26006653/

相关文章:

java:如何在不强制值类型的情况下创建动态数组?

java - 关于实现服务器端和客户端验证的问题

Java正则表达式从日志文件中获取子度量

javascript - Angularjs 正则表达式验证

java - 使用 Java Long 包装器与原始 long 添加数字

java - Date.toString() 给出的年份与设定的年份不同?

java - 处理 HardDeadlineExceededError 的任务策略

regex - 如何从 Perl 字符串中提取不同数量的数字组?

regex - 列表中的 Pandas Dataframe 通配符值

java - 连续数字的正则表达式