Как разбить 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", "}")