奇怪的结果std :: regex_replace在VS2015 [英] weird results of std::regex_replace under VS2015

查看:479
本文介绍了奇怪的结果std :: regex_replace在VS2015的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码在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;
}

奇怪的结果,第二行包含两个编译器的预期结果:

  ENDRESS\ $ 0HAUSER\ $ 0ST\ $ 0 DELL \ $ 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

我们可以看到后者有一个错误:在最后一个ABCD之前必须有两个反斜杠,而不是一个。



这是怎么回事?我写了一个手动解析器,而不是使用std :: regex_replace,但我真的想让它工作在VS2015(和任何其他IDE理想情况下),并使选择手动解析解决方案之前的基准。

解决方案

VS2015默认编译器不处理 $ 0 作为零返回引用。 您需要使用nativeECMAScript <$



此外,
revo是正确的,以便匹配 \ 您需要将它添加到字符类。



请注意,在VS2015中,您可以使用原始字符串文字。最好的做法是使用原始字符串文字来定义正则表达式模式,因为它们有助于避免 overescaping (也称为

 <$ c $ 

c> std :: cout< std :: regex_replace(pszTestString,
std :: regex(R([ - +!\\\\ [\](){} ^〜* ?:] |&& ; | \ | \ |)),\\ $&)<< std :: endl;
^^ ^^


The code below doesn't give the same result in Visual Studio 2015 and IDEOne.com (C++14). More strange, in both cases the results are incorrect !

#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;
}

Under Visual Studio 2015 I got this strange result, the second line contains the expected result for both compilers :

ENDRESS\$0HAUSER\$0ST\$0DELL\$0HP\$0BESTMATCH\$0ABCD\ABCD
ENDRESS\+HAUSER\*ST\-DELL\!HP\||BESTMATCH\&&ABCD\\ABCD

With IDEOne (C++14 compiler) :

ENDRESS\+HAUSER\*ST\-DELL\!HP\||BESTMATCH\&&ABCD\ABCD
ENDRESS\+HAUSER\*ST\-DELL\!HP\||BESTMATCH\&&ABCD\\ABCD

We can see in the latter that there is a mistake : before the last "ABCD" there must be two backslashes and not a single one

What the heck is going on ? I wrote a manual parser instead of using std::regex_replace for the moment, but I really want make it work under VS2015 (and any other IDE ideally) and make a benchmark before choosing the manual parsing solution.

解决方案

VS2015 default compiler does not treat $0 as a zeroth backreference. You need to use the "native" ECMAScript $& backreference to refer to the whole match from inside the replacement pattern.

Also, revo is right, in order to match \ you need to add it to the character class.

And note that in VS2015 you can use raw string literals. It is best practice to use raw string literals to define regex patterns as they help avoid overescaping (also called as backslash hell).

Solution:

std::cout << std::regex_replace(pszTestString, 
      std::regex(R"([-+!\\\"\[\](){}^~*?:]|&&|\|\|)"), "\\$&") << std::endl;
                        ^^                                ^^

这篇关于奇怪的结果std :: regex_replace在VS2015的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆