下面的代码在Visual Studio 2015和IDEOne.com(C ++ 14)中没有给出相同的结果。更奇怪的是,在这两种情况下结果都不正确!
#include <iostream>
#include <regex>
int main()
{
const char* pszTestString = "ENDRESS+HAUSER*ST-DELL!HP||BESTMATCH&&ABCD\\ABCD";
const char* pszExpectedString = "ENDRESS\\+HAUSER\\*ST\\-DELL\\!HP\\||BESTMATCH\\&&ABCD\\\\ABCD";
std::cout << std::regex_replace(pszTestString, std::regex("[-+!\"\\[\\](){}^~*?:]|&&|\\|\\|"), "\\$0") << std::endl;
std::cout << pszExpectedString << std::endl;
return 0;
}
在Visual Studio 2015下,我得到了这个奇怪的结果,第二行包含两个编译器的预期结果:
ENDRESS\$0HAUSER\$0ST\$0DELL\$0HP\$0BESTMATCH\$0ABCD\ABCD
ENDRESS\+HAUSER\*ST\-DELL\!HP\||BESTMATCH\&&ABCD\\ABCD
使用IDEOne(C ++ 14编译器):
ENDRESS\+HAUSER\*ST\-DELL\!HP\||BESTMATCH\&&ABCD\ABCD
ENDRESS\+HAUSER\*ST\-DELL\!HP\||BESTMATCH\&&ABCD\\ABCD
我们可以在后者看到有一个错误:在最后一个&#34; ABCD&#34;必须有两个反斜杠而不是一个反斜杠
到底发生了什么事?我写了一个手动解析器,而不是暂时使用std :: regex_replace,但我真的想让它在VS2015(以及理想的任何其他IDE)下运行,并在选择手动解析解决方案之前制作基准。
答案 0 :(得分:1)
VS2015默认编译器不会将$0
视为第0个反向引用。 您需要使用"native" ECMAScript $&
backreference来指代替换模式中的整个匹配。
另外,revo is right,为了匹配\
,您需要将其添加到字符类中。
请注意,在VS2015中,您可以使用原始字符串文字。最佳做法是使用原始字符串文字来定义正则表达式模式,因为它们有助于避免过度使用(也称为backslash hell)。
解决方案:
std::cout << std::regex_replace(pszTestString,
std::regex(R"([-+!\\\"\[\](){}^~*?:]|&&|\|\|)"), "\\$&") << std::endl;
^^ ^^