有条件地用字符串替换正则表达式匹配

pst*_*jds 16 c++ regex visual-studio-2010 visual-c++ c++11

我试图用不同的替换模式替换字符串中的某些模式.

例:

string test = "test replacing \"these characters\"";
Run Code Online (Sandbox Code Playgroud)

我想要做的是用空字符串替换所有''和'_'以及所有其他非字母或数字字符.我创建了以下正则表达式,它似乎正确地标记,但我不知道如何(如果可能)使用执行条件替换regex_replace.

string test = "test replacing \"these characters\"";
regex reg("(\\s+)|(\\W+)");
Run Code Online (Sandbox Code Playgroud)

替换后的预期结果是:

string result = "test_replacing_these_characters";
Run Code Online (Sandbox Code Playgroud)

编辑:我不能使用提升,这就是我把它从标签中删除的原因.所以请不要回答包括提升.我必须使用标准库.可能是一个不同的正则表达式会完成目标,或者我只是坚持做两次传球.

编辑2:我不记得在\w我的原始正则表达式中包含了哪些字符,在查找之后我进一步简化了表达式.再一次,目标是任何匹配\ s +应该用'_'替换,匹配\ W +的任何东西都应该用空字符串替换.

rub*_*ots 25

c ++(0x,11,tr1)正则表达式在每种情况下都不起作用(stackoverflow)( gcc的这个页面查找短语regex),所以最好使用boost一段时间.

如果您的编译器支持所需的正则表达式,您可以尝试:

#include <string>
#include <iostream>
#include <regex>

using namespace std;

int main(int argc, char * argv[]) {
    string test = "test replacing \"these characters\"";
    regex reg("[^\\w]+");
    test = regex_replace(test, reg, "_");
    cout << test << endl;
}
Run Code Online (Sandbox Code Playgroud)

以上工作在Visual Studio 2012Rc中.

编辑1:要在一次传递中替换两个不同的字符串(取决于匹配),我认为这在这里不起作用.在Perl中,这可以在评估的替换表达式(/eswitch)中轻松完成.

因此,您需要两次通过,因为您已经怀疑:

 ...
 string test = "test replacing \"these characters\"";
 test = regex_replace(test, regex("\\s+"), "_");
 test = regex_replace(test, regex("\\W+"), "");
 ...
Run Code Online (Sandbox Code Playgroud)

编辑2:

如果有可能使用一个回调函数 tr()regex_replace,那么你可以修改替换出现,如:

 string output = regex_replace(test, regex("\\s+|\\W+"), tr);
Run Code Online (Sandbox Code Playgroud)

tr()做更换工作:

 string tr(const smatch &m) { return m[0].str()[0] == ' ' ? "_" : ""; }
Run Code Online (Sandbox Code Playgroud)

问题本来可以解决.不幸的是,在一些C++ 11正则表达式实现中没有这样的重载,但是Boost 有一个.以下内容适用于boost并使用一次传递:

...
#include <boost/regex.hpp>
using namespace boost;
...
string tr(const smatch &m) { return m[0].str()[0] == ' ' ? "_" : ""; }
...

string test = "test replacing \"these characters\"";
test = regex_replace(test, regex("\\s+|\\W+"), tr);   // <= works in Boost
...
Run Code Online (Sandbox Code Playgroud)

也许有一天,这将适用于C++ 11或接下来的任何数字.

问候

RBO