我在c++中使用以下方法解析字符串:
using namespace std;
string parsed,input="text to be parsed";
stringstream input_stringstream(input);
if (getline(input_stringstream,parsed,' '))
{
// do some processing.
}
使用单个字符分隔符进行解析是可以的。但是如果我想使用字符串作为分隔符呢?
例子:我想拆分:
scott>=tiger
用>=作为分隔符,这样我就可以得到斯科特和老虎。
答案已经在那里,但选择答案使用擦除功能,这是非常昂贵的,想想一些非常大的字符串(以mb为单位)。因此我使用下面的函数。
vector<string> split(const string& i_str, const string& i_delim)
{
vector<string> result;
size_t startIndex = 0;
for (size_t found = i_str.find(i_delim); found != string::npos; found = i_str.find(i_delim, startIndex))
{
result.emplace_back(i_str.begin()+startIndex, i_str.begin()+found);
startIndex = found + i_delim.size();
}
if (startIndex != i_str.size())
result.emplace_back(i_str.begin()+startIndex, i_str.end());
return result;
}
从c++ 11开始,它可以这样做:
std::vector<std::string> splitString(const std::string& str,
const std::regex& regex)
{
return {std::sregex_token_iterator{str.begin(), str.end(), regex, -1},
std::sregex_token_iterator() };
}
// usually we have a predefined set of regular expressions: then
// let's build those only once and re-use them multiple times
static const std::regex regex1(R"some-reg-exp1", std::regex::optimize);
static const std::regex regex2(R"some-reg-exp2", std::regex::optimize);
static const std::regex regex3(R"some-reg-exp3", std::regex::optimize);
string str = "some string to split";
std::vector<std::string> tokens( splitString(str, regex1) );
注:
这是对这个答案的一个小小的改进
参见std::regex_constants::optimize使用的优化技术
以防将来,有人想跳出Vincenzo Pii答案的盒子函数
#include <vector>
#include <string>
std::vector<std::string> SplitString(
std::string str,
std::string delimeter)
{
std::vector<std::string> splittedStrings = {};
size_t pos = 0;
while ((pos = str.find(delimeter)) != std::string::npos)
{
std::string token = str.substr(0, pos);
if (token.length() > 0)
splittedStrings.push_back(token);
str.erase(0, pos + delimeter.length());
}
if (str.length() > 0)
splittedStrings.push_back(str);
return splittedStrings;
}
我还修复了一些错误,以便如果字符串的开头或结尾有分隔符,函数将不会返回空字符串
#include<iostream>
#include<algorithm>
using namespace std;
int split_count(string str,char delimit){
return count(str.begin(),str.end(),delimit);
}
void split(string str,char delimit,string res[]){
int a=0,i=0;
while(a<str.size()){
res[i]=str.substr(a,str.find(delimit));
a+=res[i].size()+1;
i++;
}
}
int main(){
string a="abc.xyz.mno.def";
int x=split_count(a,'.')+1;
string res[x];
split(a,'.',res);
for(int i=0;i<x;i++)
cout<<res[i]<<endl;
return 0;
}
注:仅当分割后的字符串长度相等时才有效