【问题标题】:Splitting A String List Into Components将字符串列表拆分为组件
【发布时间】:2021-04-19 03:10:35
【问题描述】:

我正在想办法拆分以下字符串:

"2.000000, ["Me", [13, 11], "You"], [12.000000, 15.000000]"

这样我就有了一个包含以下内容的字符串向量:

2.000000
["Me", [13, 11], "You"]
[12.000000, 15.000000]

我开始使用 , 作为正则表达式,但是这会不恰当地拆分子列表 ([...])。

我该怎么做?

【问题讨论】:

    标签: c++ string split


    【解决方案1】:

    直接的解决方案是将[] 括号的余额存储在当前前缀上。 [ 给出 +1,] 给出 -1。也不要更新余额,忽略"strings"内的[]

    int balance = 0;
    
    // If balance is 0, you're outside your list:
    //   [ ... ]
    // ^ here    ^ or here
    // If balance is >= 1, you're inside list:
    // [ ... ]
    //   ^^^
    // If balance >= 2, you're inside sublist:
    // [ ..., [ ..., [...] ], ... ]
    //          ^ balance == 2
    //                ^ balance == 3 and so on
    
    // Ignore updating balance if [ and ] inside ""-s.
    // E.g. balance won't increase
    // ["["]
    //   ^ here
    // Also ignore commas here: [",", ","]
    //                            ^    ^
    bool inside_string = false;
    
    std::string current_part;
    std::vector<std::string> parts;
    
    for (char c : s) {
      if (c == '"')
         inside_string ^= true;
    
      // Both comma and closing brace if balance is 1 can end current part.
      // Current part can't end inside ""-s.
      if (balance == 1 && (c == ',' || c == ']') && !inside_string) {
        parts.push_back(std::move(current_part));
        current_part = "";
        continue;
      }
    
      if (balance >= 1) {
        // No need to add space coming right after comma.
        if (current_part.empty() && c == ' ')
          continue;
        current_part += c;
      }
    
      if (!inside_string) {
        if (c == '[') {
          ++balance;
        } else if (c == ']') {
          --balance;
        }
      }
    }
    

    Playground

    【讨论】:

      【解决方案2】:

      用正则表达式匹配嵌套括号不是一个好方法。相反,您可以遍历字符串input,并简单地跟踪您当前是否在一对括号内。如果是,并且遇到,,则在该点拆分字符串,否则忽略,

      std::vector<std::string> result;
      
      int prev = 0, in_brackets = 0;
      
      for (int i = 0; i < std::ssize(input); ++i)
      {
        if (input[i] == ',' and not in_brackets)
        {
          result.push_back(input.substr(prev, prev - i));
          prev = i + 1;
        }
        else if (input[i] == '[') in_brackets++;  // 1 more level of brackets 
        else if (input[i] == ']') in_brackets--;  // 1 less level of brackets
      }
      
      result.push_back(input.substr(prev));  // add the last chunk
      

      std::ssize 是 C++20 的一项功能,它以有符号整数的形式返回范围的大小,这样处理起来要好得多。如果您没有 C++20,则使用 std::size,并将结果手动转换为 int

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-19
        • 2019-04-16
        • 1970-01-01
        • 1970-01-01
        • 2015-09-01
        • 2011-11-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多