类reluctanct和简单类正则表达式的等价性

时间:2015-05-13 12:11:49

标签: java regex

这是一个只是为了满足我的好奇心的问题。请考虑以下两个Java正则表达式:[, !.][, !.]+?。它们是等价的吗?我试图提出他们不相同的例子,但我找不到。

编辑: 我理解为了匹配整个String,它们不是等价的。但是当你使用它们在字符串中找到子串的多个匹配时,它们似乎与我相同。

2 个答案:

答案 0 :(得分:3)

这是同一个String中的一个自包含示例,因为你的角色类贪婪,不情愿或没有量词匹配。

Pattern greedy = Pattern.compile("[, !.]+");
Pattern reluctant = Pattern.compile("[, !.]+?");
Pattern nonQuantified = Pattern.compile("[, !.]");
String example = "foo !! bar";
Matcher greedyMatcher = greedy.matcher(example);
Matcher reluctantMatcher = reluctant.matcher(example);
Matcher nonQMatcher = nonQuantified.matcher(example);
while (greedyMatcher.find()) {
    System.out.printf("Greedy found: %s%n", greedyMatcher.group());
}
while (reluctantMatcher.find()) {
    System.out.printf("Reluctant found: %s%n", reluctantMatcher.group());
}
while (nonQMatcher.find()) {
    System.out.printf("Non-quantified found: %s%n", nonQMatcher.group());
}

<强>输出

Greedy found:  !! 
Reluctant found:  
Reluctant found: !
Reluctant found: !
Reluctant found:  
Non-quantified found:  
Non-quantified found: !
Non-quantified found: !
Non-quantified found: 

<强>解释

  • 贪婪将尽可能地匹配。因此,find一次返回truegroup()凝固整场比赛
  • 不情愿的人会尽可能少地匹配。因此,find每次匹配都会返回true一次&#34;示例&#34; Stringgroup,已调用4次,返回一个空格,一个!,另一个!和最后一个空格
  • 非量化将在每次调用时只匹配一个字符,因此就像在这种情况下不情愿的量词一样
  • Here有关量词的官方文档
  • Here是Java Pattern上的官方API,对量词语法很有用

注意

  • 正如所指出的,你的问题显示了两个字符类,但第一个没有量化。
  • 我继续假设你想把它量化为贪婪,因此我的例子中的[, !.]+,而不是你问题中的非量化[, !.]

答案 1 :(得分:2)

当您将{strong> Matcher.find()一起使用时,它们是等效的。

[, !.]+?,在匹配所需的一次重复之后,将尝试续集(在这种情况下,它是模式的结尾,因此它是接受节点) ,并返回单个字符匹配。

因此,当与[, !.]一起使用时,它在逻辑上与Matcher.find()相同。

由于量词的懒惰,只有在续集失败时才会尝试更多的重复,如果你在其后添加其他东西,或者使用带有Matcher.matches()的正则表达式(仅接受当你到达字符串的末尾时匹配。)