std :: regex_replace给了我意想不到的结果

我在C ++ Windows项目(Visual Studio 2010)中使用std::regex_replace 。 代码如下所示:

 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); 

我希望result"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://([az]+\\.)?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/" 

 "http://([^@:/]+\\.)?wik(ipedia|imedia)\\.org/" 

也就是说,用一对反斜杠替换两个单反斜杠中的每一个。

编辑:虽然这似乎并没有影响到这个问题。 在我尝试的两个实现(微软和叮当声),原来的问题不会发生,与我们没有加倍反斜杠。 (没有,你会得到关于无效转义序列的编译器警告,但是结果.通配符与目标序列中的.字符匹配,就像\.一样)