正则表达式,替换所有出现的子组
问题描述:
我想用“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的就摆在那里。
答
下面的代码是广义的。支持PCRE,PCRE2和STL正则表达式库
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
聪明,但它并不完全是我想到了。它涵盖了我不得不承认的例子,但是我需要一个解决方案,其中子组可以出现在括号内的任何位置。 – Adelost 2014-12-04 21:06:01