有没有办法在一次迭代中进行任意数量的正则表达式替换?

时间:2015-02-04 17:13:13

标签: c++ regex algorithm

假设我有一个字符串s,并希望进行N替换:

[regex_1] --> [str_1]

[regex_2] --> [str_2]

...

[regex_N] --> [str_N]

是否有比创建N regex_iterator个对象更有效的方法?因为如果我做了像

这样的事情
std::vector<std::regex_iterator> reps = { 
   std::regex_iterator(s.begin(), s.end(), [regex_1]), 
   std::regex_iterator(s.begin(), s.end(), [regex_2]), 
   ..., 
   std::regex_iterator(s.begin(), s.end(), [regex_N])};

然后所有N个对象的regex_iterator初始化将涉及迭代s的字符,这是不必要的重复。

1 个答案:

答案 0 :(得分:1)

这取决于您期望的结果。

如果您要查找的是找到任何N模式的连续非重叠事件,那么多迭代器解决方案不仅效率低下;这是不正确的。

另一方面,如果您想在替换后重新扫描模式,那么您可以订购扫描(如示例中所示),但它只是部分重新扫描。使用C ++正则表达式库可以实现精确而有效的解决方案,但这并不容易;一个精确且不那么有效的解决方案是重复找到并替换模式的第一个分离,直到找不到模式。

无论哪种方式,您都需要一个正则表达式来表示候选模式的析取(备选集),并且可以让您识别匹配的模式。如果您不太依赖捕获,可以通过创建析取(在模式上使用字符串连接)来完成此操作:

(pattern1)|(pattern2)|...|(patternN)

在匹配之后,您只需要通过迭代子匹配并查看其matched成员来确定哪个捕获具有已定义的值。当然,内部捕获是可能的,但捕获的编号使得构造有点脆弱。可以通过编程方式确定正则表达式中的捕获数量(请参阅basic_regex::mark_count),这样您就可以创建一个多模式搜索和替换对象,而不需要 进行大量工作。