一、wsregex_token_iterator实现宽字符串分割
在日常开发中一定有很多情况下需要用到对宽字符串进行分割,尤其是一些路径的分割下面这段代码借助了c++标准库,实现了将给定的宽字符的内容,按照特定的标识符,分割成若干段,存在vector数组中,具体用法如下:
1.1 分割结果不去重
#include <iterator>
#include <regex>
#include <vector>
std::vector<std::wstring> ws_split(const std::wstring& in, const std::wstring& delim)
{
std::wregex re{ delim };
return std::vector<std::wstring> {
std::wsregex_token_iterator(in.begin(), in.end(), re, -1),
std::wsregex_token_iterator()
};
}
具体调用就是
std::wstring str = L"111\\c|111\\c|111\\c";
auto s_res = ws_split(str, L"[|]");
最后就可以分割出下面三个部分
111\c
111\c
111\c
1.2 分割结果去重
如果对结果有去重的需求,可以直接将结果存在set中,避免了再次判断每个字符串是否相同,具体用法如下所示。
#include <iterator>
#include <regex>
#include <set>
std::set<std::wstring> ws_split(const std::wstring& in, const std::wstring& delim)
{
std::wregex re{ delim };
return {
std::wsregex_token_iterator(in.begin(), in.end(), re, -1),
std::wsregex_token_iterator()
};
}
1.3 其他字符串类型分割
如果实际中要处理的字符串是其他常见类型char、wchar_t、string、wstring,还可以考虑替换上面的wsregex_token_iterator这个部分,具体可以参考下面的表格
std::cregex_token_iterator | std::regex_token_iterator<const char*> |
std::wcregex_token_iterator | std::regex_token_iterator<const wchar_t*> |
std::sregex_token_iterator | std::regex_token_iteratorstd::string::const_iterator |
std::wsregex_token_iterator | std::regex_token_iteratorstd::wstring::const_iterator |
二、std::regex_token_iterator详解
具体可以参考官网上的[详细解释](std::regex_token_iterator - cppreference.com)
2.1 定义
template<
class BidirIt,
class CharT = typename std::iterator_traits<BidirIt>::value_type,
class Traits = std::regex_traits<CharT>
> class regex_token_iterator
2.2 含义
std::regex_token_iterator 是一个只读的 LegacyForwardIterator,用于访问底层字符序列中正则表达式每次匹配的各个子匹配。它还可以用于访问未被给定正则表达式匹配的序列的部分(例如,作为分词器)。
在构造时,它构造一个 std::regex_iterator,并在每次增量时从当前的 match_results 中逐步遍历请求的子匹配,当从最后一个子匹配增量时,增加底层的 std::regex_iterator。
默认构造的 std::regex_token_iterator 是序列的末尾迭代器。当有效的 std::regex_token_iterator 在到达最后一个匹配的最后一个子匹配后增量时,它将变为等于末尾迭代器。进一步解引用或增量将调用未定义的行为。
在成为末尾迭代器之前,std::regex_token_iterator 可能成为后缀迭代器,如果请求的子匹配索引列表中出现索引 -1(未匹配的片段)。这样的迭代器,如果解引用,将返回一个与最后一次匹配和序列末尾之间的字符序列相对应的 match_results。
std::regex_token_iterator 的典型实现包含底层的 std::regex_iterator,一个包含请求的子匹配索引的容器(例如 std::vector<int>),与子匹配索引相等的内部计数器,指向当前匹配的当前子匹配的 std::sub_match 指针,以及包含最后一个未匹配字符序列的 std::match_results 对象(在分词器模式中使用)。