拆分具有多个分隔符的字符串并将其保存到向量中

Posted

技术标签:

【中文标题】拆分具有多个分隔符的字符串并将其保存到向量中【英文标题】:Spliting a string with multiple delimiter and save it into a vector 【发布时间】:2015-02-17 09:20:46 【问题描述】:

我知道有很多主题都存在像我这样的问题,但我找不到特别适合我的问题的正确答案。

我想通过倍数分隔符(' ''\n''('')')将我的字符串拆分为标记并将所有内容保存在我的向量中(甚至是分隔符)。

这是我制作的第一个代码,它实际上只占用所有行,但现在我想将它与其他分隔符分开。

std::vector<std::string> Lexer::getToken(std::string flow)

    std::string token;
    std::vector<std::string> tokens;
    std::stringstream f;

    f << flow;
    while (std::getline(f, token, '\n'))
    
        tokens.push_back(token);
    
    return (tokens);

例如,如果我有:

push int32(42)

我想要以下代币:

push

int32

(

42

)

【问题讨论】:

但是您没有保存分隔符,它不在您添加到容器中的token 中? @Nim :目前没有,但我也想保存它们。 自己滚没意义,别人已经辛苦了! ***.com/questions/22331648/… 【参考方案1】:

我会为此使用正则表达式:

#include <regex>

std::vector<std::string> getToken(std::string const &flow) 
  // Delimiter regex. Depending on your desired behavior, you may want to
  // remove the + from it; with the +, it will combine adjacent delimiters
  // into one. That is to say, "foo (\n) bar" will be tokenized into "foo",
  // "bar" instead of "foo", "", "", "", "", "bar".
  std::regex re("[ \n()]+");

  // range-construct result vector from regex_token_iterators
  return std::vector<std::string>(
      std::sregex_token_iterator(flow.begin(), flow.end(), re, -1),
      std::sregex_token_iterator()
    );

【讨论】:

确实是个好主意,但我想尽可能避免使用正则表达式^^' 在词法分析器中?这有点不寻常。适合你自己,但我有点惊讶你还没有溺水。【参考方案2】:

如果您仔细考虑所涉及的状态,您可以使用每个字符的逻辑来做到这一点......

std::vector<std::string> tokens;
std::string delims = " \n()";
char c;
bool last_was_delim = true;
while (f.get(c))
    if (delims.find(c) != tokens.end())
    
        tokens.emplace_back(1, c);
        last_was_delim = true;
    
    else
    
        if (last_was_delim)
             tokens.emplace_back(1, c); // start new string
        else
             tokens.back() += c; // append to existing string
        last_was_delim = false;
    

显然这认为"(("" "(两个空格)是重复的不同分隔符,分别输入tokens。必要时调整口味。

等效地,但使用流控制而不是 bool / 不同的 while (f.get(c)) 循环处理正在进行的令牌的其他字符:

std::vector<std::string> tokens;
std::string delims = " \n()";
char c;
while (f.get(c))
    if (delims.find(c) != tokens.end())
        tokens.emplace_back(1, c);
    else
    
        tokens.emplace_back(1, c); // start new string
        while (f.get(c))
            if (delims.find(c) != tokens.end())
            
                tokens.emplace_back(1, c);
                break;
            
            else
                tokens.back() += c; // append to existing string
    

或者,如果您喜欢goto 语句:

std::vector<std::string> tokens;
std::string delims = " \n()";
char c;
while (f.get(c))
    if (delims.find(c) != tokens.end())
      add_token:
        tokens.emplace_back(1, c);
    else
    
        tokens.emplace_back(1, c); // start new string
        while (f.get(c))
            if (delims.find(c) != tokens.end())
                goto add_token;
            else
                tokens.back() += c; // append to existing string
    

哪个“更容易”理解是值得商榷的......

【讨论】:

以上是关于拆分具有多个分隔符的字符串并将其保存到向量中的主要内容,如果未能解决你的问题,请参考以下文章

拆分字符串并将其存储到 HashMap java 8

如何在python中拆分具有多个分隔符的字符串? [复制]

如何拆分具有多个分隔符powershell的字符串?

如何在 LookML 中拆分具有多个分隔符的字符串?

如何在 Ruby 中拆分分隔字符串并将其转换为数组?

将字符串拆分为具有多个分隔符的多个字符串而不删除?