C ++ 11正则表达式多行:为什么组([^ \\ 0] + \ n)?some_text的所有内容都匹配[1]?

时间:2014-05-05 23:10:45

标签: c++ regex visual-studio-2010 c++11

我试图更好地理解正则表达式。我使用的是Visual Studio 2010.以此表达式为例。在Visual Studio 2010中,您无法使用[\s\S]跳过换行符,因此我听说可以使用[^\0]。在表达式中,我想匹配一行,但仅限于line 3

if(regex_search("line 1\nline 2\nline 3\n",
    match,
    regex("^([^\\0]+\\n)?line (3)\\n")))
{
    cout << "match.length(): " << match.length() << endl;

    for(unsigned i = 0; i < match.size(); ++i)
    {
        cout << "match[" << i <<"]: \"" << match[i] << "\"" << endl;
    }
}

请注意上述代码不适用于gcc&lt; 4.9或ideone(因为它使用gcc <4.9)。

在Visual Studio 2010中,代码返回:

match.length(): 21
match[0]: "line 1
line 2
line 3
"
match[1]: "line 1
line 2
line 3
"
match[2]: "3"

我确定有更好的方法来匹配线路,但我的问题是为什么匹配[1]组匹配整个输入?我认为正则表达式会为匹配[1]读取line 1\nline 2\n并停止,因为我在正则表达式后面有line 3。在正则表达式中是否有一个单词或者它是一个错误?

谢谢,如果您有编辑权限,欢迎您进行编辑,以便更容易理解。

2 个答案:

答案 0 :(得分:1)

对于记录,这适用于Visual Studio并找到第三行,返回&#34;第3行::

^(?<=(?:[^\n]+\n){2})[^\n]+

至于你的表达,

^([^\0]+\n)?line (3)\n

我们必须决定您是否尝试在 Visual Studio的查找功能中匹配,或者在 Visual Studio 中创建控制台程序。这是两个非常不同的案例。

:一种。在Visual Studio的查找功能

在Visual Studio的查找功能中,如果您制作如下文本文件:

line 1
line 2
line 3

你的正则表达式不匹配。为什么?因为在line 3之后,您无法在Visual Studio文件中找到\n。相反,在换行符处,您会发现\r\n这是标准的Windows换行符。

添加\r修复了它:

^([^\0]+\n)?line (3)\r\n

话虽这么说,这个正则表达式匹配任意一行,而不仅仅是第3行,原因很简单,[^\0]会占用所有字符,包括新行,然后回溯到它在最后一个新行之前,\nline 3\n代币在哪个阶段完成匹配。如果你想使用[^ \ 0]而不是[^ \ n],这肯定会匹配第3行:

^(?<=([^\0]+?\n){2})line 3\r\n

<强> B中。在Visual Studio中构建的控制台应用程序

如果您向控制台应用程序提供字符串"line 1\nline 2\nline 3\n",则原始正则表达式匹配。但是,它匹配所有三行,由于上面提到的原因([^\0]吃掉所有字符,包括换行符,然后回溯到最后一行之前,\nline 3\n令牌完成匹配。)

在这里,如果你只想要第3行并使用[^\0],你可以使用它,例如:

^(?<=([^\0]+?\n){2})line 3\n

答案 1 :(得分:1)

我很确定我在Visual Studio 2010中获得的match[1]结果是由于错误造成的。

在Visual Studio 2012和2013以及gcc 4.9.0(20140405)中,代码返回我期望的内容:

match.length(): 21
match[0]: "line 1
line 2
line 3
"
match[1]: "line 1
line 2
"
match[2]: "3"

在线正则表达式测试人员RegExrRegex Hero显示相同的内容。

在Visual Studio 2010中,为了使表达式正常工作,我可以通过在加号后添加问号使其“懒惰”:"^([^\\0]+?\\n)?line (3)\\n"。 (这是一个字符串文字,因此每个反斜杠都使用反斜杠进行转义。)虽然现在可以正常工作(但不同之处在于它现在找到最接近的匹配,因为它很懒)我确信最好只使用最新的Visual Studio。

clang-503.0.40 has a different but related bug无法处理“[^ \ 0] *”。