regex_iterator与regex_token_iterator核心差异及结果适配方法问询
regex_iterator与regex_token_iterator的核心差异及实用技巧
一、二者差异的本质原因
这俩迭代器的核心差异完全源于设计定位的不同:
regex_iterator是完整匹配迭代器:它的职责是遍历字符串中所有符合正则表达式的完整匹配结果,每个迭代元素是match_results<BidirIt>对象——这个对象不仅包含整个匹配的字符串,还能访问正则里定义的所有捕获组内容。你看到的“按正则定义的token分割”,本质是它逐个返回每一个完整匹配项。regex_token_iterator是灵活令牌提取器:它的设计目标是从匹配结果中提取特定片段,或者实现字符串分割。它的迭代元素是sub_match<BidirIt>(单个匹配片段的视图),支持通过参数控制返回内容:- 传入
0:返回完整匹配(和regex_iterator的每个结果的str()效果一致) - 传入正整数
N:返回第N个捕获组的内容 - 传入
-1:返回匹配之间的非匹配部分,相当于把正则作为分隔符分割字符串
- 传入
至于你提到cppreference没提-1参数的问题,其实是有的,只是藏在构造函数的参数说明里——它接受vector<int>或者initializer_list<int>,其中元素可以是捕获组索引,或者-1表示取非匹配区间。
二、将regex_iterator结果直接存入vector的方法
regex_iterator的元素是match_results,不能直接隐式转换成string,但可以通过显式转换实现快速存入:
方法1:用std::transform批量转换
这是最简洁的方式,配合lambda表达式完成转换:
#include <regex> #include <vector> #include <algorithm> #include <string> int main() { std::string input = "foo 123 bar 456 baz"; std::regex num_re(R"(\d+)"); std::vector<std::string> nums; std::transform( std::sregex_iterator(input.begin(), input.end(), num_re), std::sregex_iterator(), std::back_inserter(nums), [](const std::smatch& match) { return match.str(); } ); // nums 现在是 {"123", "456"} return 0; }
方法2:手动遍历转换
如果觉得transform不够直观,也可以直接遍历迭代器逐个处理:
std::vector<std::string> nums; std::sregex_iterator it(input.begin(), input.end(), num_re); std::sregex_iterator end_it; for (; it != end_it; ++it) { nums.push_back(it->str()); }
为什么regex_token_iterator可以直接存?
因为sub_match<BidirIt>类型支持隐式转换为std::string,所以迭代器的元素可以直接赋值给string,不需要额外转换步骤。
内容的提问来源于stack exchange,提问作者Damir Tenishev
相关产品推荐
相关产品推荐

