我试图更好地理解正则表达式。我使用的是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
。在正则表达式中是否有一个单词或者它是一个错误?
谢谢,如果您有编辑权限,欢迎您进行编辑,以便更容易理解。
答案 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]
会占用所有字符,包括新行,然后回溯到它在最后一个新行之前,\n
,line 3
和\n
代币在哪个阶段完成匹配。如果你想使用[^ \ 0]而不是[^ \ n],这肯定会匹配第3行:
^(?<=([^\0]+?\n){2})line 3\r\n
<强> B中。在Visual Studio中构建的控制台应用程序
如果您向控制台应用程序提供字符串"line 1\nline 2\nline 3\n"
,则原始正则表达式匹配。但是,它匹配所有三行,由于上面提到的原因([^\0]
吃掉所有字符,包括换行符,然后回溯到最后一行之前,\n
,line 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"
在线正则表达式测试人员RegExr和Regex Hero显示相同的内容。
在Visual Studio 2010中,为了使表达式正常工作,我可以通过在加号后添加问号使其“懒惰”:"^([^\\0]+?\\n)?line (3)\\n"
。 (这是一个字符串文字,因此每个反斜杠都使用反斜杠进行转义。)虽然现在可以正常工作(但不同之处在于它现在找到最接近的匹配,因为它很懒)我确信最好只使用最新的Visual Studio。
clang-503.0.40 has a different but related bug无法处理“[^ \ 0] *”。