一、用<string>的getline函数
istream& getline ( istream& is , string& str , char delim ) ;
参数解释:
istream& is :包含 被分割的string信息 的输入流
string& str :获取分割结果
char delim :分隔符
代码1:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string text = "Hello World ! My name is XXX . Nice to meet you . bla bla bla";
string t;
string res[16];
int index = 0;
stringstream in;
in.str(text);
while (getline(in, t, ' ')) {
res[index++] = t;
}
for (int i = 0; i < index; i++)
cout << i << ':' << res[i] << '\n';
return 0;
}
输出:
1.1、一个输入流,对同一数据,多次用不同分隔符分割
当你循环分割完一遍后,需要重置输入流的状态,并将指针重新指向第一个字符,然后才可以对字符串使用不同分割符重新分割,因为此时输入流中的指针指向字符串末尾,再次使用getline分割无法得到预期结果。
in.clear()重置in的状态
in.seekg(0) 将指针重新指向第一个字符
代码2:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string text = "Hello World ! My name is XXX . Nice to meet you . bla bla bla";
string t;
string res[16];
int index = 0;
stringstream in;
in.str(text);
while (getline(in, t, ' ')) {
res[index++] = t;
}
for (int i = 0; i < index; i++)
cout << i << ':' << res[i] <<'\n';
cout << "\nclear\n" <<endl;
index = 0;
in.clear();
in.seekg(0);
while (getline(in, t, 'e')) {
cout <<index++<<':'<< t << '\n';
}
return 0;
}
输出:
如果你没有循环分割全部字符串,则只需in.seekg(0)回到第一个字符,就可重新getline分割了
1.2、更换字符串,再分割
in.str( newString )重新设置输入流中的字符串
若你把原先的字符串全部分割完了,再更换字符串的话,需要用in.clear()重置输入流状态,然后再用in.str(newString)更换字符串,分割
若没有全部分割完,则直接in.str(newString),然后分割
代码3:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string text = "Hello World ! My name is XXX . Nice to meet you . bla bla bla";
string t;
string res[16];
int index = 0;
stringstream in;
in.str(text);
while (getline(in, t, ' ')) {
res[index++] = t;
//if (index == 5)
// break;
}
for (int i = 0; i < index; i++)
cout << i << ':' << res[i] <<'\n';
cout << "\nclear\n" <<endl;
index = 0;
in.clear();
//in.seekg(0);
in.str(res[0]);
while (getline(in, t, 'e')) {
cout <<index++<<':'<< t << '\n';
}
return 0;
}
输出:
二、regex分割
regex pattern(“正则表达式”) (“[ ^ \\d ] +”) 匹配不含数字的字符串
regex pattern (R"(正则表达式)") (R"( [ ^ \d ] +)")
两种写法效果相同,但是转义字符 \ 的使用要注意
smatch match
regex_match(string input , smatch match ,pattern)判断input是否匹配pattern的格式
regex_search(string input , smatch match,pattern)获取第一个匹配的string
代码:
#include <iostream>
#include <regex>
using namespace std;
int main() {
string text = "Hello World ! My name is XXX . Nice to meet you . bla bla bla";
smatch res;
regex pattern(R"([^\s]+)");
//regex pattern("[^\\s]+");//效果与上方一样,匹配非空格的字符串
regex_search(text, res, pattern);
cout << res.str(); //输出 Hello
return 0;
}
sregex_token_iterator
first(input.begin() , input.end() , pattern ) 默认情况下,提取分隔符之间的文本
last 未进行任何赋值初始化操作的话,默认为一个结束迭代器
代码:
#include <iostream>
#include <regex>
#include <vector>
using namespace std;
vector<string> split(string input ,regex pattern) {
sregex_token_iterator first( input.begin(), input.end(), pattern), last;
return { first, last };
}
int main() {
string text = "Hello World ! My name is XXX . Nice to meet you . bla bla bla";
smatch res;
regex pattern(R"([^\s]+)");
//regex pattern("[^\\s]+");//效果与上方一样,匹配非空格的字符串
//regex_search(text, res, pattern);
auto res_str = split(text, pattern);
for (auto str : res_str)
cout << str << std::endl;
return 0;
}
输出:
为什么返回 { first, last }
:
-
正确构造:使用
{ first, last }
构造vector
是正确使用方式。这会从first
迭代器开始,直到last
(结束迭代器),将所有通过迭代器得到的值复制到新创建的vector
中。 -
包含所有元素:
{ first, last }
确保了从first
到last
之间的所有元素都被包含在新创建的vector
中。last
是一个结束迭代器,表示序列的结束。 -
初始化列表:使用初始化列表
{ first, last }
是一种便捷的方式来初始化vector
,避免手动复制每个元素。
如果只返回 first
:
-
如果你只返回
first
迭代器,编译器会报错,因为sregex_token_iterator
没有复制构造函数或赋值运算符,不能直接作为函数返回值。first
是一个迭代器对象,不是一个可以包含所有分割结果的容器。 -
迭代器本身不存储分割结果,所以不能单独作为分割函数的返回值。你需要一个容器(如
vector
)来存储迭代器遍历过程中的所有元素。
记住,迭代器本身不拥有任何元素,它们只是提供了访问容器中元素的一种方式。因此,要保存迭代器遍历过程中得到的元素,你需要将它们存储到一个容器中。
三、find与substr组合
find ( 查找的目标字符串 )
find ( 查找的目标字符串 ,起始查找位置)
find如果没有找到目标,会返回-1;若找到,则返回匹配字符串的第一个字符的下标
substr ( 起始位置 , 截取长度 )
代码:
#include <iostream>
#include <string>
using namespace std;
void split(string input, string res[], string delim,int& length) {
int pos = input.find(delim), start = 0, end = pos;
int index = 0;
int input_length = input.length();
while (end>0) {
res[index++] = input.substr(start, end - start);
start = end + delim.length();
end = input.find(delim, start);
}
res[index] = input.substr(start, input_length - start + 1);
length = index;
}
int main() {
string text = "Hello this is World ! My name is XXX . Nice to meet you . bla bla bla";
string res[20];
int length = 0;
split(text, res, " i",length);
for (int i = 0; i <= length; i++) {
cout << res[i] << endl;
}
return 0;
}
输出:
End