提问人:markt1964 提问时间:8/1/2023 最后编辑:Some programmer dudemarkt1964 更新时间:8/4/2023 访问量:72
将字符串拆分为字符串向量
split a string by a vector of strings
问:
我有一个输入字符串,我还有一个分隔符向量。
我想输出不在分隔符中的字符串向量,并作为附加条目输出找到的分隔符
例如,给定
"AB<sep1>DE<sep1><sep2>" where "<sep1>" and "<sep2>" are separators
输出将是向量
"AB", "<sep1>", "DE", "<sep1>", "<sep2>"
有没有一种有效的方法来实现这一点?
答:
0赞
Radovm
8/1/2023
#1
这取决于您希望实现的速度以及极端情况下的预期行为。下面是一个实现示例:
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
因此,此特定算法将 和 之间的 nothing 视为令牌。<sep1>
<sep2>
评论
1赞
chrysante
8/1/2023
这个实现被破坏了,请看这里它在测试字符串上的表现。尝试直接在循环之前声明。此外,分隔符标记应该是输出向量的一部分:-)"AB<sep2>BC<sep1>DE<sep1>test"
size_t pos = 0;
while
1赞
chrysante
8/1/2023
#2
下面是一个可能的实现。
#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;
}
}
它首先查找并收集字符串中所有分隔符实例的位置。然后它对它们进行排序,以便我们可以遍历位置并提取所有子字符串。
请注意,如果一个分隔符包含另一个分隔符作为子字符串,这将崩溃,但我认为这将是一个病态的情况。如果指定了两次分隔符,它也会中断。
评论
find
和substr
函数可能很有用。