Search code examples
c++qtqstring

How can i split a QString by a delimiter and not if that delimiter is somewhere enclosed in square-brackets


If i have a QString in the form of QString s = QString("A:B[1:2]:C:D"); i want somehow to split by ':', but only, if not enclosed in square-brackets.

So the desited output of the above QString woud be "A", "B[1:2]", "C", "D"

Right now, I can only think of something like replacing ':' in the range of s.indexOf('[') and s.indexOf(']'), then split and afterwards replace back to ':' in any remaining split, but that seems rather inconvenient.

EDIT: based on comments and answers: any number in square-brackets shall be the same after splitting. There are characters, e.g.: ';' that i can use t as temporary replacement for ':'

Any better idea?


Solution

  • Usually, I like the idea of using a regular expression here for split directly, but I could not come up with one quickly. So here it your idea of first replacing the unwanted colon with something else (here a semicolon) and then split on the remaining colons and replace the semicolon back to a colon on the separate strings.

    #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]");
        }
    }
    

    The output:

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