【问题标题】:How can i split a QString by a delimiter and not if that delimiter is somewhere enclosed in square-brackets我如何通过分隔符拆分 QString 而不是该分隔符是否包含在方括号中
【发布时间】:2016-05-30 12:18:55
【问题描述】:

如果我有一个QString s = QString("A:B[1:2]:C:D"); 形式的 QString,我想以某种方式用':' 分割,但前提是没有用方括号括起来。

所以上述QString 的期望输出应该是"A", "B[1:2]", "C", "D"

现在,我只能想到在s.indexOf('[')s.indexOf(']') 的范围内替换':',然后拆分,然后在任何剩余的拆分中替换回':',但这似乎很不方便。

编辑:基于 cmets 和答案:方括号中的任何数字在拆分后都应相同。有字符,例如:';'我可以使用 t 作为 ':' 的临时替代品

有更好的主意吗?

【问题讨论】:

    标签: c++ qt qstring


    【解决方案1】:

    通常,我喜欢在这里直接使用正则表达式进行拆分的想法,但我无法快速想出一个。所以在这里你的想法是首先用其他东西(这里是分号)替换不需要的冒号,然后拆分剩余的冒号并将分号替换回单独字符串上的冒号。

    #include <QDebug>
    #include <QRegularExpression>
    #include <QString>
    
    int main()
    {
        QString string("A:B[1:2]:C:D");
    
        // This replaces all occurences of "[x:y]" by "[x;y]" with
        // x and y being digits.
        // \\[ finds exactly the character '['. It has to be masked
        // by backslashes because it's a special character in regular
        // expressions.
        // (\\d) is a capture for a digit that can be used in the
        // resulting string as \\1, \\2 and so on.
        string = string.replace(QRegularExpression("\\[(\\d):(\\d)\\]"), "[\\1;\\2]");
    
        // split on the remaining colons
        QStringList elements = string.split(':');
    
        // Iterate over all fractions the string was split into
        foreach(QString element, elements) {
            // Replace the semicolons back to colons.
            qDebug() << element.replace(QRegularExpression("\\[(\\d);(\\d)\\]"), "[\\1:\\2]");
        }
    }
    

    输出:

    "A"
    "B[1:2]"
    "C"
    "D"
    

    【讨论】:

    • 但是数字的信息将永远丢失。我需要一个保持数字不变的解决方案。
    • 保留数字。不过,我会更新我的答案。 :)
    • 这需要[0-9]范围内的任何数字,但输出将始终为[1:2]
    • @tobilocker: \\1 和 \\2 是从正则表达式捕获的内容。因此,如果我将原始 [1:2] 替换为 [4:8],它会在此处输出正确使用的数字。
    • 好的,我现在来测试一下。谢谢:)
    【解决方案2】:

    可能远非最佳但...您可以对“:”进行初始拆分,然后对结果进行后处理以合并包含“[”和“]”的项目。因此,给定您的初始字符串,类似于...

    QString s("A:B[1:2]:C:D");
    QStringList l = s.split(':');
    for (int i = 0; i < l.size(); ++i) {
      if (l[i].contains('[')) {
        l[i] += ":" + l[i +1];
        l.takeAt(i + 1);
      }
    }
    

    当然,这假设任何给定的 '[', ']' 对最多有一个中间的 ':'。

    【讨论】:

      【解决方案3】:

      我将提供我的工作代码作为答案,但接受任何更好的想法:

      所以首先我替换方括号内的任何冒号:

      QString ShuntingYard::replaceIndexColons(QString& expression)
      {
          int index = 0;
          while (expression.indexOf('[', index) != -1)
          {
              int open = expression.indexOf('[', index);
              int close = expression.indexOf(']', open);
              int colon = expression.indexOf(':', open);
              if (colon > open && colon < close)
                  expression.replace(colon, 1, ';');
              index = open + 1;
          }
          return expression;
      }
      

      然后,我可以用splitExpression分割,这分割了几个分隔符,包括:

      expression = replaceIndexColons(expression);
      QStringList list = splitExpression(expression);
      Q_FOREACH(QString s, list)
      {
          s.replace(";", ":");
      }
      

      然后把它重新组合起来......

      【讨论】:

      • 所以你期望在你原来的QString中没有;
      • 是的 - 或者说有限制,因为字符串是一个算术表达式,混合了三元条件和数组索引。这就是?:[start:end] 发生冲突的地方
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多