版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net/10km/article/details/80193880
关于string的分割,网上有好多好多写得很详细的文章,但基本上都是基于标准C++的。
比如下面这段代码基于strtok
函数实现的split(from 《C++之split字符串分割》):
vector<string> split(const string& str, const string& delim) { vector<string> res; if("" == str) return res; //先将要切割的字符串从string类型转换为char*类型 char * strs = new char[str.length() + 1] ; //不要忘了 strcpy(strs, str.c_str()); char * d = new char[delim.length() + 1]; strcpy(d, delim.c_str()); char *p = strtok(strs, d); while(p) { string s = p; //分割得到的字符串转换为string类型 res.push_back(s); //存入结果数组 p = strtok(NULL, d); } return res; }
看着还是有点复杂,还要用到内存复制,如果用C++11开发,基于C++11强大的STL库支持,使用std::regex_token_iterator
和std::vector
容器的迭代器参数构造函数vector (InputIterator first, InputIterator last,const allocator_type& alloc = allocator_type())
这个split功能可以写得更加简单:
#include <iostream> #include <vector> #include <iterator> #include <regex> /* 用delim指定的正则表达式将字符串in分割,返回分割后的字符串数组 delim 分割字符串的正则表达式 */ std::vector<std::string> s_split(const std::string& in, const std::string& delim) { std::regex re{ delim }; // 调用 std::vector::vector (InputIterator first, InputIterator last,const allocator_type& alloc = allocator_type()) // 构造函数,完成字符串分割 return std::vector<std::string> { std::sregex_token_iterator(in.begin(), in.end(), re, -1), std::sregex_token_iterator() }; }
如上只要2行代码就可以完成正则表达式的字符串分割。
如果要支持宽字符集和c string,上面的函数还可以衍生出下面的不同版本:
// std::wstring版本 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() }; } // c string版本 std::vector<std::string> c_split(const char* in, const char* delim) { std::regex re{ delim }; return std::vector<std::string> { std::cregex_token_iterator(in, in + strlen(in),re, -1), std::cregex_token_iterator() }; } // 支持wchar_t宽字符集的版本 std::vector<std::wstring> wc_split(const wchar_t* in, const wchar_t* delim) { std::wregex re{ delim }; return std::vector<std::wstring> { std::wcregex_token_iterator(in, in + wcslen(in),re, -1), std::wcregex_token_iterator() }; } // 上面的s_split和ws_split可以统一用模板来实现 template<typename E, typename TR = std::char_traits<E>, typename AL = std::allocator<E>, typename _str_type = std::basic_string<E, TR, AL>> std::vector<_str_type> bs_split(const std::basic_string<E, TR, AL>& in, const std::basic_string<E, TR, AL>& delim) { std::basic_regex<E> re{ delim }; return std::vector<_str_type> { std::regex_token_iterator<typename _str_type::const_iterator>(in.begin(), in.end(), re, -1), std::regex_token_iterator<typename _str_type::const_iterator>() }; }
#include <iostream> #include <vector> #include <iterator> #include <regex> int main() { auto s_result = s_split("hello,do you ;know the word?", "[\\s,;?]+"); std::copy(s_result.begin(), s_result.end(), std::ostream_iterator<std::string>(std::cout, "\n")); auto c_result = c_split("hello,do you ;know the word?", "[\\s,;?]+"); std::copy(c_result.begin(), c_result.end(), std::ostream_iterator<std::string>(std::cout, "\n")); // 设置locale使std::wcout支持中文输出 std::wcout.imbue(std::locale(std::locale(), "", LC_CTYPE)); auto ws_result = ws_split(L"lao ban 老板,来份 小龙虾,快点啊!?", L"[\\s,;?]+"); std::copy(ws_result.begin(), ws_result.end(), std::ostream_iterator<std::wstring, std::wstring::value_type>(std::wcout, L"\n")); }
文章: 《C++ Split string into a vector》 《C++之split字符串分割》 《std::regex_token_iterator》 《constructor of std::vector::vector》
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句