C++ std::regex多行语法

6

我似乎无法正确使用正则表达式。在ECMAScript的多行文本中,这个正则表达式begin\n([\s\S]*\nend)?匹配了我需要的内容,我在这里进行过测试

当我将它翻译成C++时,它无法匹配相同的文本。

这是我的Visual C++ 2010代码:

#include <iostream>
#include <regex>

int main(int argc, char *argv[]) {
    std::regex metadataBlockRegex("begin\\n([\\s\\S]*\\nend)?",
        std::regex::ECMAScript);

    std::string text =
      "begin\n"
      "  123\n"
      "end\n";

    std::sregex_iterator blocksBegin(text.begin(), text.end(), metadataBlockRegex);
    std::sregex_iterator blocksEnd;

    for (auto blockMatch = blocksBegin; blockMatch != blocksEnd; ++blockMatch) {
            std::cout << (*blockMatch)[0].str();
    }
    return 0;
}

这里只输出了"begin",而我希望它能匹配整个文本。我的问题是:这里有什么问题,我在哪里可以找到有关std::regex引擎语法及其如何处理多行字符串的详细说明。

这个程序使用clang++/libc++打印整个文本(除了最后一个未匹配的\n)。 - Cubbi
这在MSVC10中的行为与Gart所描述的一致。换行符不匹配,其后的任何内容也不匹配。 - John Dibling
同时使用 boost::regex 输出整个字符串。 - Jonathan Wakely
看起来这是特定于MSVC10实现的。 - Gart
2个回答

5

没有多行支持,无论如何...在MSVC10中都不支持。

您需要在模式中使用\r和\n来模拟多行。这是一个很大的麻烦。


0

LWG 2503 添加了multiline语法选项,当您使用该选项时(对于支持该新功能的C++实现),应该可以使您的程序按预期工作。

LWG 2343 提供了更多背景信息,解释了ECMAScript RegExp对象具有默认为false的Multiline属性以及不同C++ regex实现的行为。

2012年的原始答案:

这里有什么问题吗?

不确定,看起来没问题,但我只能访问不支持<regex>的C++11实现。

在哪里可以找到std::regex引擎语法及其如何处理多行字符串的详细描述。

据我所知,你不能这样做。最好的地方可能是查看Boost.Regex的文档,但请注意,自从它被提议标准化以来,它已经有了一些不在std::regex中的功能。

Josuttis有关于不同正则表达式语法差异的描述。你看到的行为与egrep语法一致,其中\n分隔交替模式,因此begin是第一个模式的有效匹配项。然而,ECMAScript语法不应该像那样处理\n。 - Jonathan Wakely

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接