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 中做到这一点。

运行: http://cpp.sh/5ndl

#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 }表示输出不匹配的内容,然后输出匹配的内容。如果你要输入 12 那将意味着输出正则表达式组 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/