C++ Split string based on/using (boost) 正则表达式来查找令牌
C++ Split string based on/using (boost) regex to find the token
我需要根据通过正则表达式找到的标记将字符串拆分为 "string chunks"。我还需要将令牌本身保存为最终字符串块的一部分
这是显示我所追求的复杂性的正则表达式和输入字符串:https://regex101.com/r/bR9gW9/1
我试着做了一个简单的例子,但编译失败:http://cpp.sh/9qifd
#include <iostream>
#include <string>
#include <boost/regex.hpp>
#include <vector>
using namespace std;
int main()
{
string data = "TAKE some stuff\nTAKE other stuff\nTAKE more stuff\n";
boost::regex separate_take_chunks("TAKE");
vector<string> take_chunks;
//boost::sregex_token_iterator i(data.begin(), data.end(), separate_take_chunks, -1);
boost::sregex_token_iterator j;
//while (i != j) cout << *i++;
}
这里使用的是 std 正则表达式,但它没有给我令牌 http://cpp.sh/2jlv
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main()
{
string data = "TAKE some stuff\nTAKE other stuff\nTAKE more stuff\n";
std::regex separate_take_chunks("TAKE");
std::sregex_token_iterator iter(data.begin(), data.end(), separate_take_chunks, -1);
std::sregex_token_iterator end;
for ( ; iter != end; ++iter)
std::cout << *iter << "---\n";
}
这里没有使用正则表达式,但如果我可以用正则表达式替换查找函数,那么效果会很好:
size_t p1 = 4;
size_t p2 = 0;
while (p2 != string::npos) {
p2 = data.find("TAKE\n", p1);
take_chunks.push_back(data.substr(p1-4, p2));
p1 = p2+4;
}
对于第一个示例,您还没有设置 boost header 路径。我不确定你是否可以在 shell 中做到这一点。
#include <iostream>
#include <string>
#include <regex>
#include <vector>
using namespace std;
int main()
{
string data = "NAME some name stuff\nTAKE some take stuff\nTAKE SEL some take sel stuff\n";
regex separate_take_chunks("TAKE SEL|TAKE|NAME");
vector<string> take_chunks;
std::sregex_token_iterator i(data.begin(), data.end(), separate_take_chunks, { -1, 0 });
std::sregex_token_iterator j;
++i; // there is no unmatched content (-1) initially, so skip it
while (i != j) {
take_chunks.push_back(*i++); // put matched content (0) in new index
if (i != j) take_chunks.back() += *i++; // add unmatched content (-1)
}
for (const auto& c : take_chunks) cout << c << "--" <<endl;
}
{ -1, 0 }
表示输出不匹配的内容,然后输出匹配的内容。如果你要输入 1
或 2
那将意味着输出正则表达式组 1 或 2,而 { 3, 4 }
将 output/concatenate 组 3 和 4。但是我们在这里没有使用组,所以 -1 和 0 是唯一可能的输出。
最初的++i
是跳过第一个-1
(不匹配的内容)继续0
(匹配的内容),因为在第一部分之前没有不匹配的内容字符串 NAME
。
基本上这会创建一个模式:
-1(不匹配的跳过,因为它是空的)
0 + -1(连接匹配和不匹配)
0 + -1
..等等
我认为它的工作方式是正则表达式函数一旦找到匹配项就停止查找,因此当它找到 NAME 时它就完成了该迭代的内容捕获。那么 -1
为空,0
为 "NAME"。通过执行初始 ++i
,我们跳过空的 -1
。下一次迭代 -1
具有不匹配的内容,该内容在正则表达式试图查找 "TAKE" 时被捕获。因此,我们将 -1
不匹配的内容与 "NAME" 连接起来,并将 "TAKE" 放入向量的新索引中。
更多信息:http://www.cplusplus.com/reference/regex/regex_token_iterator/regex_token_iterator/
如果您想采用 position/substr 方法,另请参阅此获取匹配位置:Get the index of all matches using regex_search?
也有帮助:http://www.cplusplus.com/reference/regex/match_results/
我需要根据通过正则表达式找到的标记将字符串拆分为 "string chunks"。我还需要将令牌本身保存为最终字符串块的一部分
这是显示我所追求的复杂性的正则表达式和输入字符串:https://regex101.com/r/bR9gW9/1
我试着做了一个简单的例子,但编译失败:http://cpp.sh/9qifd
#include <iostream>
#include <string>
#include <boost/regex.hpp>
#include <vector>
using namespace std;
int main()
{
string data = "TAKE some stuff\nTAKE other stuff\nTAKE more stuff\n";
boost::regex separate_take_chunks("TAKE");
vector<string> take_chunks;
//boost::sregex_token_iterator i(data.begin(), data.end(), separate_take_chunks, -1);
boost::sregex_token_iterator j;
//while (i != j) cout << *i++;
}
这里使用的是 std 正则表达式,但它没有给我令牌 http://cpp.sh/2jlv
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main()
{
string data = "TAKE some stuff\nTAKE other stuff\nTAKE more stuff\n";
std::regex separate_take_chunks("TAKE");
std::sregex_token_iterator iter(data.begin(), data.end(), separate_take_chunks, -1);
std::sregex_token_iterator end;
for ( ; iter != end; ++iter)
std::cout << *iter << "---\n";
}
这里没有使用正则表达式,但如果我可以用正则表达式替换查找函数,那么效果会很好:
size_t p1 = 4;
size_t p2 = 0;
while (p2 != string::npos) {
p2 = data.find("TAKE\n", p1);
take_chunks.push_back(data.substr(p1-4, p2));
p1 = p2+4;
}
对于第一个示例,您还没有设置 boost header 路径。我不确定你是否可以在 shell 中做到这一点。
#include <iostream>
#include <string>
#include <regex>
#include <vector>
using namespace std;
int main()
{
string data = "NAME some name stuff\nTAKE some take stuff\nTAKE SEL some take sel stuff\n";
regex separate_take_chunks("TAKE SEL|TAKE|NAME");
vector<string> take_chunks;
std::sregex_token_iterator i(data.begin(), data.end(), separate_take_chunks, { -1, 0 });
std::sregex_token_iterator j;
++i; // there is no unmatched content (-1) initially, so skip it
while (i != j) {
take_chunks.push_back(*i++); // put matched content (0) in new index
if (i != j) take_chunks.back() += *i++; // add unmatched content (-1)
}
for (const auto& c : take_chunks) cout << c << "--" <<endl;
}
{ -1, 0 }
表示输出不匹配的内容,然后输出匹配的内容。如果你要输入 1
或 2
那将意味着输出正则表达式组 1 或 2,而 { 3, 4 }
将 output/concatenate 组 3 和 4。但是我们在这里没有使用组,所以 -1 和 0 是唯一可能的输出。
最初的++i
是跳过第一个-1
(不匹配的内容)继续0
(匹配的内容),因为在第一部分之前没有不匹配的内容字符串 NAME
。
基本上这会创建一个模式:
-1(不匹配的跳过,因为它是空的)
0 + -1(连接匹配和不匹配)
0 + -1
..等等
我认为它的工作方式是正则表达式函数一旦找到匹配项就停止查找,因此当它找到 NAME 时它就完成了该迭代的内容捕获。那么 -1
为空,0
为 "NAME"。通过执行初始 ++i
,我们跳过空的 -1
。下一次迭代 -1
具有不匹配的内容,该内容在正则表达式试图查找 "TAKE" 时被捕获。因此,我们将 -1
不匹配的内容与 "NAME" 连接起来,并将 "TAKE" 放入向量的新索引中。
更多信息:http://www.cplusplus.com/reference/regex/regex_token_iterator/regex_token_iterator/
如果您想采用 position/substr 方法,另请参阅此获取匹配位置:Get the index of all matches using regex_search?
也有帮助:http://www.cplusplus.com/reference/regex/match_results/