C++那些事之快来pick出你喜欢的字符串分割方法

C++那些事之五种方法字符串分割

通常我们在开发的时候会对一个长字符串依据分隔符进行分割,从而得到我们想要的字符串,大家都说C++字符串分割并没有那么方便,今天来总结一下5种方法分割字符串。

包含了从C++11到C++20的写法,以及C风格。

大纲

1.find分割

2.C++20 Ranges与Views分割

3.正则分割

4.istringstream分割

5.C风格的strtok分割

为了方便后续文章的讲解,我们先定义一个函数原型:

  • 参数:两个字符串,一个表示原字符串,另一个表示分隔符

  • 返回值:字符串数组

注:懒人版,可以从星球获取完整代码。

8e3aa626670bff4d924c45e6498bf989.png

1.find分割

第一种方法便是大家常用的先找到分割符的位置,然后划分字符串,添加到数组中,于是有了下面的代码。

nt start = 0;
int end = s.find(delim);
std::vector<std::string> result;
while (end != std::string::npos) {
  result.push_back(s.substr(start, end - start));
  start = end + delim.size();
  end = s.find(delim, start);
}

result.push_back(s.substr(start, end - start));

这种办法是否还能进行优化呢?

答案是肯定的,为了使得代码看起来更加优雅,我们可以每次删除前面已经输出的子串,然后find逻辑一致。

while (end != std::string::npos) {
  result.push_back(s.substr(0, end));
  s.erase(0, end + delim.size());
  end = s.find(delim);
}

2.C++20 Ranges与Views分割

C++20中我们可以使用 std::ranges::views::split() 创建一个分隔符的视图,然后使用transform,将每个子视图转换为 std::string

auto split_transform_view = s | std::ranges::views::split(delim) |
                              std::ranges::views::transform([](auto&& str) {
                                return std::string(str.begin(), str.end());
                              });

是不是很简单,可能一些人没看懂,诶关系去看之前的C++20文章吧。

3.正则分割

使用 std::regex 对象构造分隔符模式,使用std::sregex_token_iterator 遍历由正则表达式模式分隔的子字符串,-1表示提取不匹配的字符串,即除了分割符的字符串。

std::regex r(delim);
return {std::sregex_token_iterator(s.begin(), s.end(), r, -1),
        std::sregex_token_iterator()};

4.istringstream分割

getline每次只能传递一个分隔符,于是分隔之后,需要继续跳过后续的分隔符。

std::istringstream ss(s);
while (std::getline(ss, token, *(it = delim.begin()))) {
    result.push_back(token);
    it++;

    while (it != delim.end() && ss.peek() == *(it)) {
        it++;
        ss.get();
    }
}

5.C风格的strtok分割

使用 strtok() 将字符串分割成标记,然后while循环依次提取即可。

token = strtok((char*)s.c_str(), delim.c_str());
while (token != NULL) {
  result.push_back(token);
  token = strtok(NULL, delim.c_str());
}

以上便是常用的几种方法,你还有其他方法吗?欢迎留言区见,本节完整代码放于星球,欢迎订阅下载!

跟我一起实践写代码,戳这里呀~

f2ba87b77d22afbf9f981a4cbbb072d3.jpeg

往期推荐:

向量数据库milvus源码剖析之开篇

热度更新,手把手实现工业级线程池

1a5610d700ee39cd641bcb3b8ce95ee6.jpeg

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值