【问题标题】:Splitting a string into multiple strings with multiple delimiters without removing?将字符串拆分为具有多个分隔符的多个字符串而不删除?
【发布时间】:2013-10-23 08:28:40
【问题描述】:

我使用的是boost框架,所以可能会有所帮助,但我还没有找到必要的功能。

对于通常的快速拆分,我可以使用:

string str = ...;
vector<string> strs;
boost::split(strs, str, boost::is_any_of("mM"));

但它会删除 m 和 M 个字符。

我也不能简单地使用正则表达式,因为它会在字符串中搜索符合定义模式的最长值。

附:有很多类似的问题,但他们只用其他编程语言描述了这个实现。

【问题讨论】:

  • 那么,您想拆分 m M 但保留该字符?
  • 如果您希望分隔符成为字符串的一部分,拆分规范会变得模糊,您能否举例说明可能的输入以及您希望得到的输出?
  • 那么m(/M) 是第一个字符串的最后一个字符,还是第二个字符串的第一个字符?
  • m/M 将加入下一个子串

标签: c++ regex string vector split


【解决方案1】:

未经测试,但不是使用vector&lt;string&gt;,您可以尝试vector&lt;boost::iterator_range&lt;std::string::iterator&gt;&gt;(这样您就可以为每个令牌的主字符串获取一对迭代器。然后从(范围-1的开始[只要开始范围不是主字符串的begin()],到范围结束)

编辑:这是一个例子:

#include <iostream>
#include <string>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/range/iterator_range.hpp>

int main(void)
{
  std::string str = "FooMBarMSFM";

  std::vector<boost::iterator_range<std::string::iterator>> tokens;

  boost::split(tokens, str, boost::is_any_of("mM"));

  for(auto r : tokens)
  {
    std::string b(r.begin(), r.end());
    std::cout << b << std::endl;
    if (r.begin() != str.begin())
    {
      std::string bm(std::prev(r.begin()), r.end());
      std::cout << "With token: [" << bm << "]" << std::endl;
    }
  }
}

【讨论】:

    【解决方案2】:

    您的需求超出了split 的概念。如果你想保留'm 或 M',你可以用strstrstrchrstrtokfind 函数编写一个特殊的拆分。您可以更改一些代码以生成灵活的split 函数。 这是一个例子:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void split(char *src, const char *separator, char **dest, int *num)
    {
        char *pNext;
        int count = 0;
    
        if (src == NULL || strlen(src) == 0) return;
        if (separator == NULL || strlen(separator) == 0) return; 
    
        pNext = strtok(src,separator);
    
        while(pNext != NULL)
        {
            *dest++ = pNext;
            ++count;
            pNext = strtok(NULL,separator);
        }
    
        *num = count;
    }
    

    另外,你可以试试boost::regex

    【讨论】:

      【解决方案3】:

      我目前的解决方案如下(但它不是通用的,看起来太复杂了)。

      我选择了一个不能出现在这个字符串中的字符。就我而言,它是“|”。

      string str = ...;
      vector<string> strs;
      boost::split(strs, str, boost::is_any_of("m"));
      str = boost::join(strs, "|m");
      boost::split(strs, str, boost::is_any_of("M"));
      str = boost::join(strs, "|M");
      if (boost::iequals(str.substr(0, 1), "|") {
      
          str = str.substr(1);
      }
      boost::split(strs, str, boost::is_any_of("|"));
      

      我加“|”在每个符号 m/M 之前,字符串中的第一个位置除外。然后我将字符串拆分为子字符串,并删除这个额外的字符

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-29
        • 1970-01-01
        • 2021-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多