【问题标题】:A string tokenizer in C++ that allows multiple separatorsC++ 中允许多个分隔符的字符串标记器
【发布时间】:2011-02-08 21:26:29
【问题描述】:

有没有办法在 C++ 中用多个分隔符标记字符串?在 C# 中我会这样做:

string[] tokens = "adsl, dkks; dk".Split(new [] { ",", " ", ";" }, StringSplitOptions.RemoveEmpty);

【问题讨论】:

  • @Nick Presta:是的,但我看到的大多数问题只涉及使用一个分隔符。
  • 那是怎样的一个骗局?一个想只在空白处拆分,这个想在多个分隔符上拆分。
  • @Duck:几乎所有这些答案都可以适应任何分隔符(大多数已经基于参数)。除非您建议我们对每种类型的分隔符都有一个新问题?
  • 不要重新发明轮子...似乎我的链接提升::split
  • 下面的一些示例怎么样:codeproject.com/KB/recipes/Tokenizer.aspx 它们非常高效且有些优雅。字符串工具包库使 C++ 中的复杂字符串处理变得简单易行。

标签: c# c++ string tokenize


【解决方案1】:

使用 boost::tokenizer。它支持多个分隔符。

事实上,你甚至不需要 boost::tokenizer。如果您想要的只是拆分,请使用 boost::split。该文档有一个示例: http://www.boost.org/doc/libs/1_42_0/doc/html/string_algo/usage.html#id1718906

【讨论】:

    【解决方案2】:

    这样就可以了:

    void tokenize_string(const std::string &original_string, const std::string &delimiters, std::vector<std::string> *tokens)
    {
            if (NULL == tokens) return;
    
            size_t pos_start = original_string.find_first_not_of(delimiters);
            size_t pos_end   = original_string.find_first_of(delimiters, pos_start);
    
            while (std::string::npos != pos_start)
            {
                    tokens->push_back(original_string.substr(pos_start, pos_end - pos_start));
                    pos_start = original_string.find_first_not_of(delimiters, pos_end);
                    pos_end   = original_string.find_first_of(delimiters, pos_start);
            }
    }
    

    【讨论】:

      【解决方案3】:

      这是我的版本(尚未经过大量测试):

      std::vector<std::string> split(std::string const& s,
          std::vector<std::string> const& delims)
      {
          std::vector<std::string> parts;
      
          std::vector<std::pair<std::string::size_type, std::string::size_type>> poss;
          poss.reserve(delims.size());
      
          std::string::size_type beg = 0;
      
          for(;;)
          {
              poss.clear();
      
              std::string::size_type idx = 0;
              for(auto const& delim: delims)
              {
                  if(auto end = s.find(delim, beg) + 1)
                      poss.emplace_back(end - 1, idx);
                  ++idx;
              }
      
              if(poss.empty())
                  break;
      
              std::sort(std::begin(poss), std::end(poss));
      
              auto old_beg = beg;
      
              for(auto pos: poss)
              {
                  parts.emplace_back(std::begin(s) + beg,
                      std::begin(s) + old_beg + pos.first);
                  beg = pos.first + delims[pos.second].size();
              }
          }
      
          if(beg < s.size())
              parts.emplace_back(std::begin(s) + beg, std::end(s));
      
          return parts;
      }
      

      【讨论】:

        猜你喜欢
        • 2017-09-25
        • 2015-09-18
        • 1970-01-01
        • 2021-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多