更新:请仔细阅读我对jignatius答案的评论
我编写了以下代码,以使用正则表达式查找字符串中的特定匹配项,并将其删除并替换为另一个值,但是它没有按预期工作。 例如,给出以下输入:
f={a,b}+{c,d}
我希望它同时删除{a,b}
和{c,d}
,但它只能在第一个删除,我的代码有什么问题?
经过一番检查后,我看到第一个循环只输入了一次,为什么?
答案 0 :(得分:1)
标头<regex>
中有一个标准的库函数std::regex_replace
,它可以执行以下操作:基于正则表达式的文本替换。这将为您简化很多事情,而无需使用手工制作的循环。
您只需要提供输入字符串,要匹配的正则表达式和替换字符串:
#include <iostream>
#include <regex>
#include <string>
int main()
{
std::regex reg(R"(\{[^}]*\})");
std::string mystring = "f={a,b}+{c,d}";
auto newstring = std::regex_replace(mystring, reg, "title");
std::cout << newstring; //f=title+title
}
注意:使用格式为R"(literal)"
的原始字符串文字也更容易,以避免使用双反斜杠在正则表达式中转义特殊字符。
在您的评论中,您说替换文字可以更改。在这种情况下,您将需要执行循环,而不是直接进行正则表达式替换。
您可以使用std::regex_iterator
,这是一个只读的正向迭代器,它将为您调用std::regex_search()
。您可以使用字符串流来构建新字符串:
#include <iostream>
#include <regex>
#include <string>
#include <sstream>
int main()
{
std::regex reg(R"(\{[^}]*\})");
std::string mystring = "f={a,b}+{c,d} + c";
std::vector<std::string> replacements = { "rep1", "rep2", "rep3" };
int i = 0;
auto start = std::sregex_iterator(mystring.begin(), mystring.end(), reg);
auto end = std::sregex_iterator{};
std::ostringstream ss;
for (std::sregex_iterator it = start; it != end; ++it)
{
std::smatch mat = *it;
ss << mat.prefix() << replacements[i++];
//If last match, stream suffix
if (std::next(it) == end)
{
ss << mat.suffix();
}
}
std::cout << ss.str(); //f=rep1+rep2 + c
}
请注意,prefix()
对象的std::smatch
方法将为您提供从目标字符串到匹配开始的子字符串。然后,将替换文本放入流中。最后,您应该使用suffix()
对象的std::smatch
方法在最后匹配和目标字符串结尾之间流式传输任何尾随文本。