英文:
std::regex_replace to replace multiple combinations
问题
我尝试使用std::regex_replace
来替换一些字符组合为其他字符。然而,每组字符都有不同的替换字符(这取决于字符)。我考虑使用map,但由于我无法访问要替换的字符(如代码中所示),这种方法不起作用。有没有办法在一个regex_replace
语句中涵盖所有替换情况(或者也许有更好的方法)?
现有代码:
std::regex r(" c|ph|th|ea|c|w");
map<string, string> comb{
{" c", "k"},
{"ph", "f"},
{"th", "z"},
{"ea", "e"},
{"c", "s"},
{"w", "v"}
};
line = std::regex_replace(line, r, comb[r]);
英文:
I am trying to utilize the std::regex_replace to replace a few combinations of characters with other characters. However, each set of characters has a different set of characters I would like to replace it with (it depends on the character).
I thought about using a map , but that will not work as I do not have access to the character being replaced (as seen in the code). Any idea how to cover all replacement cases in one regex_replace statement (or perhaps a better approach) ?
Current Code:
std::regex r(" c|ph|th|ea|c|w");
map<string, string> comb{
{" c", "k"},
{ "ph", "f" },
{ "th", "z" },
{ "ea", "e" },
{ "c", "s" },
{ "w", "v" }
};
line = std::regex_replace(line, r, comb[r]);
答案1
得分: 1
我们可以使用regex_iterator
和您的映射一起自定义regex_replace
函数:
演示示例
首先,让我们编写一个函数,该函数接受一个std::map<string, string>
并返回一个正则表达式,该表达式只是键之间的替代 |
。这将允许我们在映射和生成的正则表达式之间保持强大的关联。
std::regex regex_from_map(const std::map<std::string, std::string>& map)
{
std::string pattern_str = "(";
auto it = map.begin();
if (it != map.end())
{
pattern_str += it->first;
for(++it; it != map.end(); ++it)
pattern_str += "|" + it->first;
}
pattern_str += ")";
return std::regex(pattern_str);
}
接下来,让我们编写一个函数,该函数接受要匹配的文本和您的替换映射,然后迭代每个匹配并找到适当的替换以构建结果字符串:
std::string custom_regex_replace(const std::string& text,
const std::map<std::string, std::string>& replacement_map)
{
auto regex = regex_from_map(replacement_map);
std::string result;
std::sregex_iterator it(text.begin(), text.end(), regex);
std::sregex_iterator end;
size_t last_pos = 0;
for (; it != end; ++it) {
result += text.substr(last_pos, it->position() - last_pos);
result += replacement_map.at(it->str());
last_pos = it->position() + it->length();
}
result += text.substr(last_pos, text.size() - last_pos);
return result;
}
最后,调用我们的自定义替换函数:
int main() {
std::map<std::string, std::string> replacement_map =
{ {" c", "k"},
{ "ph", "f" },
{ "th", "z" },
{ "ea", "e" },
{ "c", "s" },
{ "w", "v" }
};
std::string text = "each word pheels new, cnow?";
std::string new_text = custom_regex_replace(text, replacement_map);
std::cout << new_text << std::endl;
return 0;
}
输入:
> "each word pheels new, cnow?"
输出:
> "esh vord feels nev,knov?"
(请注意" c"
被替换为"k"
,所以逗号后的空格被删除)
英文:
We can hack together our own custom regex_replace
using a regex_iterator
and your map:
Live Demo
First, let's write function that accepts a std::map<string, string>
and returns a regex
that is just an alternation |
between the keys. This will let us keep a strong association between the map and the resulting regex.
std::regex regex_from_map(const std::map<std::string, std::string>& map)
{
std::string pattern_str = "(";
auto it = map.begin();
if (it != map.end())
{
pattern_str += it->first;
for(++it; it != map.end(); ++it)
pattern_str += "|" + it->first;
}
pattern_str += ")";
return std::regex(pattern_str);
}
Next, let's write a function that accepts the text to be matched and your replacement map, then iterates over each match and finds the appropriate replacement to build the result string:
std::string custom_regex_replace(const std::string& text,
const std::map<std::string, std::string>& replacement_map)
{
auto regex = regex_from_map(replacement_map);
std::string result;
std::sregex_iterator it(text.begin(), text.end(), regex);
std::sregex_iterator end;
size_t last_pos = 0;
for (; it != end; ++it) {
result += text.substr(last_pos, it->position() - last_pos);
result += replacement_map.at(it->str());
last_pos = it->position() + it->length();
}
result += text.substr(last_pos, text.size() - last_pos);
return result;
}
Finally, calling our custom replacement function:
int main() {
std::map<std::string, std::string> replacement_map =
{ {" c", "k"},
{ "ph", "f" },
{ "th", "z" },
{ "ea", "e" },
{ "c", "s" },
{ "w", "v" }
};
std::string text = "each word pheels new, cnow?";
std::string new_text = custom_regex_replace(text, replacement_map);
std::cout << new_text << std::endl;
return 0;
}
Input:
> "each word pheels new, cnow?"
Output:
> "esh vord feels nev,knov?"
(Note that " c"
is replace with "k"
, so the space after the comma was deleted)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论