【问题标题】:Tokenize a string excluding delimiters inside quotes标记字符串,不包括引号内的分隔符
【发布时间】:2011-10-24 05:49:03
【问题描述】:

首先让我说,我已经彻底解决了这个问题的所有其他解决方案,虽然它们非常相似,但没有一个能完全解决我的问题。

我需要使用 boost regex 提取除引号(对于引用的)之外的所有标记。

我认为我需要使用的正则表达式是:

sregex pattern = sregex::compile("\"(?P<token>[^\"]*)\"|(?P<token>\\S+)");

但我得到一个错误:

命名标记已存在

为 C# 发布的解决方案似乎适用于重复的命名标记,因为它是与另一个标记的 OR 表达式。

Regular Expression to split on spaces unless in quotes

【问题讨论】:

    标签: c++ regex boost boost-regex boost-xpressive


    【解决方案1】:

    我在这里回答了一个非常相似的问题:

    How to make my split work only on one real line and be capable to skip quoted parts of string?

    示例代码

    • 使用增强精神
    • 支持带引号的字符串、部分带引号的字段、用户定义的分隔符、转义引号
    • 一般支持许多(不同的)输出容器
    • 支持 Range 概念的模型作为输入(包括 char[],例如)

    使用相对广泛的编译器版本和 Boost 版本进行测试。

    https://gist.github.com/bcfbe2b5f071c7d153a0

    【讨论】:

      【解决方案2】:

      大多数正则表达式不允许重复使用组名。如果所有用途都在相同的交替范围内,则某些口味允许它,但显然您的不是其中之一。但是,如果您运行的是最新版本的 Boost,您应该能够使用分支重置组。它看起来像这样 - (?|...|...|...) - 在每个备选方案中,组编号重置为到达分支重置组之前的任何位置。它也应该适用于命名组,但这不能保证。我无法自己测试它,所以试试这个:

      "(?|\"(?P<token>[^\"]*)\"|(?P<token>\\S+))"
      

      ...如果这不起作用,请尝试使用普通的旧编号组。

      【讨论】:

      • 这似乎不起作用,即使命名标记不同,使用 boost::xpressive 的正则表达式字符串也会出现“无法识别的扩展”错误。必须与外部组语法有关。编辑:我的提升是 1.47,据我所知,这是最新的
      • 你试过用编号组吗? "(?|\"([^\"]*)\"|(\\S+))"
      【解决方案3】:

      在这里查看答案时,我测试了另一种方法,该方法涉及使用不同的组标记名称,并在迭代它们时简单地测试哪个是空白的。虽然它可能不是最快的代码,但它是迄今为止最易读的解决方案,这对我的问题更重要。

      这是对我有用的代码:

          #include <boost/xpressive/xpressive.hpp>
          using namespace boost::xpressive;
      ...
          std::vector<std::string> tokens;
          std::string input = "here is a \"test string\"";
          sregex pattern = sregex::compile("\"(?P<quoted>[^\"]*)\"|(?P<unquoted>\\S+)");
          sregex_iterator cur( input.begin(), input.end(), pattern );
          sregex_iterator end;
      
          while(cur != end)
          {
            smatch const &what = *cur;
            if(what["quoted"].length() > 0)
            {
              tokens.push_back(what["quoted"]);
            }
            else
            {
              tokens.push_back(what["unquoted"]);
            }
            cur++;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-08
        • 2014-09-26
        • 2015-09-18
        • 2015-07-19
        • 2016-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多