0

POSIX 标准规定对于 ERE 和 BRE :

与整个匹配是最左边匹配中最长的一致,每个子模式从左到右应匹配最长的可能字符串。为此,空字符串应被认为比完全不匹配要长。例如,匹配 BRE "(. ). " 和 "abcdef",子表达式 "(\1)" 是 "abcdef",匹配 BRE "(a*)*" 和 "bc",子表达式 "( \1)" 是空字符串。

我的问题:应该如何(a|ab)(c|bcd)(d*)匹配“abcd”?

我对上述标准的解读是,子表达式(a|ab)应该匹配最左边、最长的字符串,以尽可能长时间地保持整个匹配,因此子表达式应该匹配“ab”。但是,当我使用 GNU 正则表达式(a|ab)(c|bcd)(d*)在“abcd”中搜索时,我得到以下第一个子表达式:

echo abcd | sed -E 's/(a|ab)(c|bcd)(d*)/\0, \1, \2, \3/'
abcd, a, bcd, 

这个例子来自这个页面

这是使用带有 regex::extended 标志的 Boost.Regex 的 C++ 代码:

#include <boost/regex.hpp>
#include <iostream>
#include <string>

int main()
{
  boost::regex_constants::syntax_option_type regex_flags =
      boost::regex::extended;

  std::string text = "abcd";
  boost::regex expression("(a|ab)(c|bcd)(d*)", regex_flags);
  boost::smatch matches {};

  boost::regex_search(text, matches, expression);

  for (const auto match : matches) { std::cout << match << ", "; }
  std::cout << std::endl;

  return 0;
}

编译并运行,产生:

abcd, ab, c, d, 

在这里,与标准一致,子表达式(a|ab)与它可以匹配的最长匹配项匹配,但在 GNU 正则表达式中它不匹配。

4

0 回答 0