c++ 用字符串向量分割字符串

2ledvvac  于 2023-08-09  发布在  其他
关注(0)|答案(2)|浏览(104)

我有一个输入字符串,我也有一个分隔符向量。
我想输出不在分隔符中的字符串的向量,并作为一个额外的条目,找到了分隔符
例如,给定

"AB<sep1>DE<sep1><sep2>" where "<sep1>" and "<sep2>" are separators

字符串
输出将是向量

"AB", "<sep1>", "DE", "<sep1>", "<sep2>"


有没有一种有效的方法来实现这一点?

uurity8g

uurity8g1#

这是一种可能的实现方式。

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

std::vector<std::string> split(std::string const& str,
                               std::vector<std::string> const& seps) {
    std::vector<std::pair<size_t, size_t>> sepPos;
    for (auto& sep: seps) {
        if (sep.empty()) {
            continue;
        }
        size_t pos = 0;
        while ((pos = str.find(sep, pos)) != std::string::npos) {
            sepPos.push_back({ pos, pos + sep.size() });
            pos += sep.size();
        }
    }
    std::sort(sepPos.begin(), sepPos.end());
    std::vector<std::string> result;
    size_t pos = 0;
    for (auto [begin, end]: sepPos) {
        result.push_back(str.substr(pos, begin - pos));
        result.push_back(str.substr(begin, end - begin));
        pos = end;
    }
    result.push_back(str.substr(pos, str.size() - pos));
    return result;
}

字符串
最小的测试。

#include <iostream>
#include <string>
#include <vector>

#include "Split.h"

int main() {
    auto tokens = split("AB<sep1>DE<sep2>X<sep1>Y", { "<sep1>", "<sep2>" });
    for (auto& token: tokens) {
        std::cout << token << std::endl;
    }
}


它首先查找并收集字符串中所有分隔符示例的位置。然后它对它们进行排序,这样我们就可以迭代位置并提取所有子字符串。
请注意,如果一个分隔符包含另一个分隔符作为子字符串,则会出现这种情况,但我认为这是一种病态情况。如果分隔符被指定两次,它也会中断。

hgc7kmma

hgc7kmma2#

这取决于您希望实现的速度以及在极端情况下的预期行为。这是一个实现的示例:

std::string s = "AB<sep1>DE<sep1><sep2>test";
std::vector<std::string> dels = {"<sep1>", "<sep2>"};

size_t pos = 0;
std::vector<std::string> tokens;

for(auto & del : dels)
{
    while ((pos = s.find(del)) != std::string::npos) 
    {
        tokens.push_back(s.substr(0, pos));
        s.erase(0, pos + del.length());
    }
}
if(s.size() != 0)
{
    tokens.push_back(s.substr(0, pos));    
}

for(auto & token : tokens)
{
    std::cout << token << std::endl;
}

字符串
输出为:

AB
DE

test


所以这个算法把<sep1><sep2>之间的nothing算作一个令牌。

相关问题