C++ std::regex_replace给了我意外的结果
我在C++窗口项目(VisualStudio 2010)中使用<代码> STD::ReXExpRead <代码>。代码如下所示:C++ std::regex_replace给了我意外的结果,c++,regex,windows,c++11,C++,Regex,Windows,C++11,我在C++窗口项目(VisualStudio 2010)中使用 STD::ReXExpRead 。代码如下所示: std::string str("http://www.wikipedia.org/"); std::regex fromRegex("http://([^@:/]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase); std::string fmt("https://$1wik$2.org/"); std::s
std::string str("http://www.wikipedia.org/");
std::regex fromRegex("http://([^@:/]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase);
std::string fmt("https://$1wik$2.org/");
std::string result = std::regex_replace(str, fromRegex, fmt);
我希望结果
是”https://www.wikipedia.org/“
,但我得到了”https://www.wikipedia.wikipedia.org/“
使用sed
快速检查可以得到预期的结果
$ cat > test.txt
http://www.wikipedia.org/
$ sed 's/http:\/\/([^@:\/]+\.)?wik(ipedia|imedia)\.org\//https:\/\/$1wik$2.org\//' test.txt
http://www.wikipedia.org/
我不明白这种区别是从哪里来的。我检查了可与std::regex_replace
一起使用的标志,我没有看到在这种情况下有用的标志
更新
这些变体工作正常:
std::regex fromRegex("http://([^@:/]+\\.)wik(ipedia|imedia)\\.org/", std::regex_constants::icase);
std::regex fromRegex("http://((?:[^@:/]+\\.)?)wik(ipedia|imedia)\\.org/", std::regex_constants::icase);
std::regex fromRegex("http://([a-z]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase);
std::regex fromRegex("http://([^a]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase);
但不是这些:
std::regex fromRegex("http://([^1-9]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase);
std::regex fromRegex("http://([^@]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase);
std::regex fromRegex("http://([^:]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase);
这对我来说毫无意义…正则表达式中有一个细微的错误。不要忘记,编译器会扩展字符串文本中的转义序列。所以改变
"http://([^@:/]+\.)?wik(ipedia|imedia)\.org/"
到
也就是说,用一对反斜杠替换两个单个反斜杠中的每一个
编辑:不过,这似乎不会影响问题。在我尝试过的两个实现(Microsoft和clang)上,最初的问题没有出现,我们没有双重反斜杠。(如果没有,您将收到有关无效转义序列的编译器警告,但生成的
通配符与目标序列中的
字符匹配,就像\.
一样)您使用的编译器是什么?如果是GCC放弃:
未实现。改用boost。我还不知道有任何编译器支持regex。这是对编译器的最新更新吗?@sftrabbit MSVC的STL从2008版开始就有一个功能性正则表达式实现,而LLVM/Clang的libc++也有一个完整的正则表达式实现。@rubenvb我显然研究得不太好。@Mark这里有一个解释,直接从马嘴里:或者改为使用原始文字-这有助于解决倾斜牙签的问题:R“http://([^@://]+\)?wik(ipedia | imedia)\.org/”。注意前面的R.@emsr-sure,如果您有一个支持原始文本的C++11编译器。
"http://([^@:/]+\\.)?wik(ipedia|imedia)\\.org/"