用回调函数替换C++正则表达式

C++ regex replace with a callback function

本文关键字:C++ 正则表达式 替换 函数 回调      更新时间:2023-10-16

我有一个存储id到值映射的映射,一个输入字符串可以包含一堆id。我需要用它们相应的值替换那些id。例如:

string = "I am in #1 city, it is now #2 time" // (#1 and #2 are ids here)
id_to_val_map = {1 => "New York", 2 => "summer"}

期望输出:

"I am in New York city, it is now summer time"

有没有一种方法可以让我有一个回调函数(接收匹配的字符串并返回用作替换的字符串(?std::regex_replace似乎并不支持这一点。

另一种选择是找到所有匹配项,然后计算它们的替换值,然后执行实际替换。这不会那么有效。

您可以执行以下操作:

const std::map<int, std::string> m = {{1, "New York"}, {2, "summer"}};
std::string s = "I am in #1 city, it is now #2 time";
for (const auto& [id, value] : m) {
s = std::regex_replace(s, std::regex("#" + std::to_string(id)), value);
}
std::cout << s << std::endl;

演示

一种自主开发的方法是使用带有regex_search((的while循环,然后
在执行过程中构建输出字符串。

这基本上就是regex_replace((在一次传递中所做的

无需为每个映射项执行单独的regex,这会在每个项上产生
重新分配的开销(s=regex_replace(((,并且每次通过都覆盖相同的
不动产。

类似于此regex

(?s)
( .*? )                       # (1)
(?:
#
( d+ )                       # (2)
|  $
)

使用此代码

typedef std::string::const_iterator SITR;
typedef std::smatch X_smatch;
#define REGEX_SEARCH std::regex_search
std::regex _Rx =  std::regex( "(?s)(.*?)(?:\#(\d+)|$)" );
SITR start = oldstr.begin();
SITR end   = oldstr.end();
X_smatch m;
std::string newstr = "";
while ( REGEX_SEARCH( start, end, m, _Rx ) )
{
newstr.append( m[1].str() );
if ( m[2].matched ) {
{
// append the map keys value here, do error checking etc..
// std::string key = m[2].str();
int ndx = std::atoi( m[2].str() );
newstr.append( mymap[ ndx ] );
}
start = m[0].second;
}
// assign the old string with new string if need be
oldstr = newstr;