std::regex_token_iterator
在标头 <regex> 定义 | ||
template< class BidirIt, | (C++11 起) | |
std::regex_token_iterator
是访问底层字符序列内每个正则表达式匹配的单独子匹配的只读老式向前迭代器(LegacyForwardIterator) 。它也可以用于访问没有匹配到给定的正则表达式的序列部分(例如作为记号化器)。
构造时,它构造一个 std::regex_iterator,而在每次自增时,它越过请求的来自当前匹配结果的子匹配,并在自增离开上个子匹配时自增底层的 std::regex_iterator。
默认构造的 std::regex_token_iterator
是序列尾迭代器。在抵达最后匹配的最后子匹配自增合法的 std::regex_token_iterator
时,它变得等于序列尾迭代器。进一步解引用或自增它会引发未定义行为。
在恰好变成序列尾迭代器前,如果请求的子匹配下标列表中出现了 -1(非匹配片段),那么 std::regex_token_iterator
可成为后缀迭代器。解引用这种迭代器会返回对应最后匹配和序列结尾之间的字符序列的 match_results
。
std::regex_token_iterator
的典型实现保有底层的 std::regex_iterator、请求的子匹配下标的容器(例如 std::vector<int>)、等于子匹配下标的内部计数器、指向当前匹配的当前子匹配的指向 std::sub_match 指针和含有最近非匹配字符序列的 std::match_results 对象(用于记号化器模式)。
目录 |
[编辑]类型要求
-BidirIt 必须满足老式双向迭代器(LegacyBidirectionalIterator) 。 |
[编辑]特化
对常用字符序列类型定义了数个特化:
在标头 <regex> 定义 | |
类型 | 定义 |
std::cregex_token_iterator | std::regex_token_iterator<constchar*> |
std::wcregex_token_iterator | std::regex_token_iterator<constwchar_t*> |
std::sregex_token_iterator | std::regex_token_iterator<std::string::const_iterator> |
std::wsregex_token_iterator | std::regex_token_iterator<std::wstring::const_iterator> |
[编辑]成员类型
成员类型 | 定义 |
value_type | std::sub_match<BidirIt> |
difference_type | std::ptrdiff_t |
pointer | const value_type* |
reference | const value_type& |
iterator_category | std::forward_iterator_tag |
iterator_concept (C++20) | std::input_iterator_tag |
regex_type | std::basic_regex<CharT, Traits> |
[编辑]成员函数
构造新的 regex_token_iterator (公开成员函数) | |
(析构函数) (隐式声明) | 析构 regex_token_iterator ,包含其缓存值 (公开成员函数) |
赋值内容 (公开成员函数) | |
(C++20 移除) | 比较两个 regex_token_iterator (公开成员函数) |
访问当前子匹配 (公开成员函数) | |
推进迭代器到下一个子匹配 (公开成员函数) |
[编辑]注解
程序员负责确保传递给迭代器构造函数的 std::basic_regex 对象活得久于迭代器。因为迭代器存储 std::regex_iterator,它存储指向正则表达式的指针,所以在销毁正则表达式后自增迭代器会导致未定义行为。
[编辑]示例
#include <algorithm>#include <fstream>#include <iostream>#include <iterator>#include <regex> int main(){// 记号化(不匹配片段)// 注意正则表达式仅匹配了两次:在获得第三个值时迭代器是后缀迭代器。conststd::string text ="Quick brown fox.";conststd::regex ws_re("\\s+");// 空白符std::copy(std::sregex_token_iterator(text.begin(), text.end(), ws_re, -1), std::sregex_token_iterator(), std::ostream_iterator<std::string>(std::cout, "\n")); std::cout<<'\n'; // 迭代首个子匹配conststd::string html = R"(<p><a href="http://google.com">google</a> )" R"(< a HREF ="http://cppreference.com">cppreference</a>\n</p>)";conststd::regex url_re(R"!!(<\s*A\s+[^>]*href\s*=\s*"([^"]*)")!!", std::regex::icase); std::copy(std::sregex_token_iterator(html.begin(), html.end(), url_re, 1), std::sregex_token_iterator(), std::ostream_iterator<std::string>(std::cout, "\n")); }
输出:
Quick brown fox. http://google.com http://cppreference.com
[编辑]缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 3698 (P2770R0) | C++20 | regex_token_iterator 是贮藏迭代器,但它是 forward_iterator | 使之为 input_iterator [1] |
- ↑解决方案没有修改
iterator_category
,因为把它改成 std::input_iterator_tag 会影响到很多现有代码。