c++使用单词列表作为分隔符拆分字符串

C++ split string using a list of words as separators

本文关键字:分隔符 拆分 字符串 列表 单词 c++      更新时间:2023-10-16

我想分割这样一个字符串

“this1245is@g$0,therhsuidthing345”

使用像下面这样的单词列表

{“this”, “is”, “the”, “thing”}

进入这个列表

{“this”, “1245”, “is”, “@g$0,”, “the”,  “rhsuid”, “thing”, “345”}
// ^--------------^---------------^------------------^-- these were the delimiters

分隔符允许在要分割的字符串中出现多次,这可以使用正则表达式

来完成

优先级按照分隔符在数组

中出现的顺序排列。

我开发的平台不支持Boost库

这是我目前拥有的

#include <iostream>
#include <string>
#include <regex>
int main ()
{
    std::string s ("this1245is@g$0,therhsuidthing345");
    std::string delimiters[] = {"this", "is", "the", "thing"};
    for (int i=0; i<4; i++) {
        std::string delimiter =  "(" + delimiters[i] + ")(.*)";
        std::regex e (delimiter);   // matches words beginning by the i-th delimiter
        // default constructor = end-of-sequence:
        std::sregex_token_iterator rend;
        std::cout << "1st and 2nd submatches:";
        int submatches[] = { 1, 2 };
        std::sregex_token_iterator c ( s.begin(), s.end(), e, submatches );
        while (c!=rend) std::cout << " [" << *c++ << "]";
        std::cout << std::endl;
    }
    return 0;
}
输出:

1st and 2nd submatches:[this][x1245fisA@g$0,therhsuidthing345]
1st and 2nd submatches:[is][x1245fisA@g$0,therhsuidthing345]
1st and 2nd submatches:[the][rhsuidthing345]
1st and 2nd submatches:[thing][345]

我想我需要做一些递归的东西在每次迭代中调用

构建只匹配(re)的表达式,然后将{-1, 0}传递给std::sregex_token_iterator以返回所有不匹配(-1)和匹配(0)。

#include <iostream>
#include <regex>
int main() {
   std::string s("this1245is@g$0,therhsuidthing345");
   std::regex re("(this|is|the|thing)");
   std::sregex_token_iterator iter(s.begin(), s.end(), re, { -1, 0 });
   std::sregex_token_iterator end;
   while (iter != end) {
      //Works in vc13, clang requires you increment separately,
      //haven't gone into implementation to see if/how ssub_match is affected.
      //Workaround: increment separately.
      //std::cout << "[" << *iter++ << "] ";
        std::cout << "[" << *iter << "] ";
        ++iter;
   }
}

我不知道如何执行优先级要求。这似乎对给定的输入有效:

std::vector<std::string> parse (std::string s)
{
    std::vector<std::string> out;
    std::regex re("(this|is|the|thing).*");
    std::string word;
    auto i = s.begin();
    while (i != s.end()) {
        std::match_results<std::string::iterator> m;
        if (std::regex_match(i, s.end(), m, re)) {
            if (!word.empty()) {
                out.push_back(word);
                word.clear();
            }
            out.push_back(std::string(m[1].first, m[1].second));
            i += out.back().size();
        } else {
            word += *i++;
        }
    }
    if (!word.empty()) {
        out.push_back(word);
    }
    return out;
}
vector<string> strs; 
boost::split(strs,line,boost::is_space());