正则表达式,替换所有出现的子组

问题描述:

我想用“b”替换括号内的所有“a”。正则表达式,替换所有出现的子组

我:

std::string s = "a(aaa)a"; 
std::regex e("(\\(.*?)(a)(.*\\))"); 
s = std::regex_replace(s, e, "$1b$3"); 

std::cout << s << std::endl; 

它输出:

a(baa)a 

但我想:

a(bbb)a 

似乎唯一适当的解决方案是做两个正则表达式搜索。一个提取括号子字符串,然后在该字符串上执行第二个正则表达式。

std::string in = "a(a a)a(a) a"; 
std::regex re("\\(.*?\\)"); 
std::smatch m; 
std::string out; 
while (std::regex_search(in, m, re)) 
{ 
    out += m.prefix(); 
    std::regex re("a"); 
    out += std::regex_replace(m[0].str(), re, "b"); 
    in = m.suffix(); 
} 
out += in; 

std::cout << out << std::endl; 

输入:

a(a a)a(a) a" 

输出:

a(b b)a(b) a 

我不认为你可以直接与std::regex_replace做到这一点;它似乎没有涵盖任何相关的正则表达式格式规范。但是,你可以简单地做这样的事情:

std::string s = "a(aaa)a"; 
std::regex re("(.*\\()(a*)(\\).*)"); // Regex amended to capture all a's between() 
std::smatch m; 

std::regex_search(s, m, re); 
s = m.format("$1" + std::string(m[2].length(), 'b') + "$3"); // match length known here 

因为所有你真正需要的,除了比赛就知道是你有多少B的就摆在那里。

+1

聪明,但它并不完全是我想到了。它涵盖了我不得不承认的例子,但是我需要一个解决方案,其中子组可以出现在括号内的任何位置。 – Adelost 2014-12-04 21:06:01

下面的代码是广义的。支持PCREPCRE2STL正则表达式库

bool U::String::replaceExAll(string &s, const string& replace_this_reg_ex, const string& replace_with, bool case_sensitive, bool extended) 
{ 
#ifdef UTIL_USE_PCRE 
    pcrecpp::RE_Options options; 
    options.set_utf8(true); 
    options.set_caseless(!case_sensitive); 
    pcrecpp::RE(replace_this_reg_ex, options).GlobalReplace(replace_with, &s); 
    return true; 
#elif UTIL_USE_PCRE2 
    jp8::Regex re(replace_this_reg_ex); 
    jp8::RegexReplace& rp = re.initReplace(); 
    rp.setSubject(s) 
       .setReplaceWith(replace_with) 
       .setBufferSize(s.length() * 2); 
    if(!case_sensitive) 
     rp.addPcre2Option(PCRE2_CASELESS); 
    if(extended) 
     rp.addPcre2Option(PCRE2_SUBSTITUTE_EXTENDED); 
    rp.addPcre2Option(PCRE2_SUBSTITUTE_GLOBAL); 
    // PCRE2_DOTALL PCRE2_MULTILINE PCRE2_UTF does not work 

    s = rp.replace(); 
    return re.getErrorNumber() == 0; 
#else 
    regex rx = regex(replace_this_reg_ex, case_sensitive ? 0 : regex_constants::icase);; 
    std:string temp = std::regex_replace(s, rx, replace_with); 
    s = temp; 

    return true; 
#endif 
} 
+0

请格式化您的代码,不要使用新建/删除。谢谢。 – 2017-02-25 23:24:00

+0

@over_optimistic答案更新。 – 2017-03-02 07:30:35

这将做的工作:

const std::string in = "a(aaa)a"; 
const std::regex re("(\\(.*?)(a)(.*\\))"); 

std::string out = in; 
while (std::regex_search(out, re)) { 
    out = std::regex_replace(out, re, "$1b$3"); 
} 

std::cout << in << std::endl; 
std::cout << out << std::endl; 

输出:

a(aaa)a 
a(bbb)a