regex_replace,为什么会丢失$ 1?

时间:2018-06-28 07:24:33

标签: 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, )

我想将'替换为(Quotation, ),并且我不想丢失原始的'。因此,我使用$1来表示原始的'。而且我不想替换'中的I'd

^表示如果'在字符串的开头,它将被替换。 $表示字符串的结尾。

结果应该是:

  

'(报价,)我去。 (引号)

但实际上结果是

  

'(报价,)我去。(报价,)

用左引号替换可以正常工作,但是用右引号代替'。为什么?

2 个答案:

答案 0 :(得分:10)

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

((^| )')|('($| ))
|| 2 |   |
|  1   | | | 4 |
         |  3   |

您可以使用$1$2$3$4来引用每个组,甚至还可以使用{{ 1}} 替换后向引用

因此添加$&可以解决问题:

$3

请参见C++ demo

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

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

s = std::regex_replace(s, std::regex("(?:^|\\s)'|'(?!\\S)"), "$&(Quotation, )"); 正则表达式匹配

  • (?:^|\s)'|'(?!\S)-字符串或空白字符的开头,后跟(?:^|\s)'
  • '-或
  • |-一个'(?!\S),后跟空格或字符串结尾。

'在替换时将匹配项重新插入到结果中。在线查看此regex demo(不要在那里关注替换,该站点不支持$&反向引用)。

注意:如果使用的是最新的编译器,则在定义正则表达式$&时可以使用原始字符串文字。

答案 1 :(得分:1)

您的正则表达式中不需要多个“或”。试试这个:^\s*(').*(')\s*$ 并替换后向引用。

相关问题