regex_replace,为什么会失去$ 1?

Zha*_*ang 5 c++ regex c++11 visual-studio-2017

string s = " 'I'd go.' ";
s = std::regex_replace(s, std::regex("((^| )')|('($| ))"), "$1(Quotation, )");
cout << s; // '(Quotation, )I'd go.(Quotation, )
Run Code Online (Sandbox Code Playgroud)

我想更换'(Quotation, )的,我不想失去原来的'.所以,我用$1的意思是原作'.我不想更换'I'd.

^意味着如果'它位于字符串的开头,它将被替换. $表示字符串的结尾.

结果应该是:

'(报价,)我会去的.(报价)

但实际上结果是

'(报价,)我去.(报价单)

左引号替换工作正常,但右边输了'.为什么?

Wik*_*żew 10

之所以会发生这种情况,是因为'字符串的末尾是在第3组中捕获的:

((^| )')|('($| ))
|| 2 |   |
|  1   | | | 4 |
         |  3   |
Run Code Online (Sandbox Code Playgroud)

你可以参考每个组的$1,$2,$3$4等等,你可以使用甚至提到了整场比赛$& 更换反向引用.

所以添加$3可以解决问题:

s = std::regex_replace(s, std::regex("((^| )')|('($| ))"), "$1$3(Quotation, )");
// =>  '(Quotation, )I'd go.' (Quotation, )
Run Code Online (Sandbox Code Playgroud)

请参阅C++演示

替代解决方案可能看起来像

s = std::regex_replace(s, std::regex("(?:^|\\s)'|'(?!\\S)"), "$&(Quotation, )");
Run Code Online (Sandbox Code Playgroud)

(?:^|\s)'|'(?!\S)正则表达式匹配

  • (?:^|\s)'- 开始字符串或空白字符和'后面的字符串
  • | - 要么
  • '(?!\S)- '后跟一个空格或字符串结尾.

$&刀片在比赛时更换回的结果.在线看到这个正则表达式演示(不要注意那里的替换,该站点不支持$&反向引用).

注意:如果您使用的是最新的编译器,则在定义regexp时可以使用原始字符串文字R"((?:^|\\s)'|'(?!\\S))".