VS13 C ++贪婪的比赛不够贪婪

时间:2015-06-15 12:50:40

标签: c++ regex visual-studio-2013

请考虑以下代码:

wstring String = L"HMM";
wsmatch Matches; 
if( regex_match( String, Matches, wregex( L"(H+|M+)([^HM]*)(H+|M+)([^HM]*)(H+|M+)" ) ) )
    wcout << Matches[1].str() << L"-" << Matches[3].str() << L"-" << Matches[5].str() << endl;
else
    wcout << L"No match\n";

您会希望第二个M+会贪婪地消耗所有M,然后给我们No match作为结果。相反,我们得到H-M-M作为结果。

看起来VS13试图最大化子匹配数量并牺牲贪婪吗?

3 个答案:

答案 0 :(得分:2)

+表示一个或多个,并且您有三个组需要一个或多个H和M,这就是为什么你在每个组中得到其中一个。

(H+|M+)  # Would like to match H
([^HM]*) # Accepted since you allow 0 occurrences
(H+|M+)  # Would like to match MM, but can only M
([^HM]*) #
(H+|M+)  # This NEEDS to match the last H or M

贪婪意味着它会尽可能地匹配,但它决不会因贪婪而牺牲匹配。

答案 1 :(得分:1)

正则表达式中有5个捕获组。所有这些都包含贪婪的模式。这意味着不会向邻近的团体发放任何角色。

  • (H+|M+) - 贪婪地匹配Hs或Ms,但仅匹配H或M以外的下一个字符或空格。为什么包括空格?因为....
  • ([^HM]*) - 匹配空字符串或非H或非M贪婪。
  • (H+|M+) - 再次,贪婪地匹配1个或多个Hs或Ms,直到空字符串或非H或非M
  • ([^HM]*) - 与上述相同
  • (H+|M+) - 与上述相同。

在regex101.com上,捕获的空字符串位于非参与组中,您可以在网站选项中将其打开。

您还可以查看正则表达式在http://regexstorm.net/tester上的行为方式。在“表”选项卡上,您将始终看到所有捕获的子字符串。

答案 2 :(得分:1)

  

您会希望第二个M+会贪婪地消耗所有M,然后给我们No match作为结果。

您所描述的行为是 possessive ,而非贪婪。贪婪的量词消耗尽可能多的消耗量,然后尽可能多地回馈以实现整体匹配。

在支持它们的风格中,通过在正常量词之后添加+来形成占有量词。这个正则表达式将按照您的预期行事:

(H++|M++)([^HM]*+)(H++|M++)([^HM]*+)(H++|M++)

但是,您使用的味道不支持占有量词。 Atomic groups可以用于同一件事,但你也没有。