c++11:基于STL实现字符串分割更简单 wstring,string split

本文介绍了一种使用C++11的std::regex_token_iterator和std::vector容器进行字符串分割的方法,支持多种字符集和字符串类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于string的分割,网上有好多好多写得很详细的文章,但基本上都是基于标准C++的。
比如下面这段代码基于strtok函数实现的split(from [《C++之split字符串分割》][2]):

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][3]和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》][1]
[《C++之split字符串分割》][2]
[《std::regex_token_iterator》][3]
[《constructor of std::vector::vector》][4]
[1]:https://codereview.stackexchange.com/questions/159628/c-split-string-into-a-vector?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
[2]:https://blog.csdn.net/mary19920410/article/details/77372828
[3]:http://en.cppreference.com/w/cpp/regex/regex_token_iterator
[4]:http://www.cplusplus.com/reference/vector/vector/vector/

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值