Как разбить QString и сохранить разделитель в Qt?

У меня есть QString: "{x, c | 0x01}", и я хочу разделить его на 7 токенов, как показано ниже:

{
x
,
c
|
0x01
}

Какой лучший способ сделать это в Qt?

Я пытался использовать QString::split(QRegExp("[\\{\\},|]")), но он НЕ сохраняет разделитель в результате.

3 ответа

Решение

Может быть, это решение может служить вам задачу:

int main(void) {
    QString str { "{x, c | 0x01}" };
    QRegExp separators { "[\\{\\},|]" };

    QStringList list;
    str.replace( " ", "" );

    int mem = 0;
    for(int i = 0; i<str.size(); ++i) {
        if(i == str.indexOf(separators, i)) {
            if(mem) list.append(str.mid(mem, i-mem)); // append str before separator
            list.append(str.mid(i, 1));               // append separator
            mem = i+1;
        }
    }

    qDebug() << list;

    return 0;
}

Выходы: ("{", "x", ",", "c", "|", "0x01", "}")

Вы можете устранить if(mem) но потом используй list.pop_front(); или жеlist.removeAll(""); после for цикл, в качестве первого элемента будет мусор "",


По сути, вы перебираете строку, проверяете, найден ли разделитель, и добавляете разделитель в список. Если разделитель не найден, в список добавляется новое слово, и до тех пор, пока не будет найден следующий разделитель, в слово будут добавлены символы. Взглянуть:

 //input string
QString str = "{x, c | 0x01}";
QList<QString> out;

//flag used to keep track of whether we're adding a mullti-char word, or just a deliminator
bool insideWord = false;

//remove whitespaces
str = str.simplified();
str = str.replace(" ", "");

//iterate through string, check for delims, populate out list
for (int i = 0; i < str.length(); i++)
{
    QChar c = str.at(i);    //get char at current index
    if (c == '{' || c == '}' || c == ',' || c == '|')
    {
        //append deliminator
        out.append(c);
        insideWord = false;
    }
    else
    {
        //append new word to qlist...
        if (!insideWord)
        {
            out.append(c);
            insideWord = true;
        }
        //but if word already started
        else
        {
            //add 'c' to the word in last index of the qlist
            out.last().append(c);
        }
    }
}

//output as requested by OP
qDebug() << "String is" << out;

Это может быть сделано в одном регулярном выражении, но должно использовать упреждающий просмотр.

Выражение, указанное в вопросе ([\\{\\},|]) будет соответствовать 1-символьной длинной строке, состоящей из любых символов {, }, , или же |, QString.split затем удалит эту 1-символьную длинную строку.

Требуется найти строку из нулевого символа непосредственно перед каждым из этих разделителей, используя предварительный просмотр: (?=[\\{\\},|]) а также найти строку из нулевого символа сразу после разделителя (?<=[\\{\\},|]),

Сочетание этих дает:

QString::split(QRegularExpression("(?=[\\{\\},|])|(?<=[\\{\\},|])"))

Который даст желаемый результат: ("{", "x", ",", "c", "|", "0x01", "}")

Другие вопросы по тегам