Reputation: 2108
I have a QString: "{x, c | 0x01}", and I want to split it to 7 tokens as below:
{
x
,
c
|
0x01
}
What's the best way to do it in Qt?
I tried to use QString::split(QRegExp("[\\{\\},|]"))
, but it DOES NOT keep the separator in the result.
Upvotes: 5
Views: 4002
Reputation: 802
This can be done in a single regular expression, but has to use look-ahead and look-behind.
The expression specified in the question ([\\{\\},|]
) will match a 1-character long string consisting of any of the characters {
, }
, ,
or |
. QString.split will then remove that 1-character long string.
What is needed is to find the zero-character string immediately before each of those separators, using a look-ahead: (?=[\\{\\},|])
and also to find the zero-character string immediately after the separator (?<=[\\{\\},|])
.
Combining these gives:
QString::split(QRegularExpression("(?=[\\{\\},|])|(?<=[\\{\\},|])"))
Which will give the desired output: ("{", "x", ",", "c", "|", "0x01", "}")
Upvotes: 0
Reputation: 1484
Maybe this solution can serve you task:
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;
}
Outputs: ("{", "x", ",", "c", "|", "0x01", "}")
You can eliminate if(mem)
but then use list.pop_front();
orlist.removeAll("");
after the for
cycle, as first element will be a rubbish ""
.
Upvotes: 1
Reputation: 814
Basically, you iterate through the string, check if a deliminator is found, and add the deliminator to the list. If no deliminator is found, a new 'word' is added to the list, and until the next deliminator is found, characters will be added to the word. Take a look:
//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;
Upvotes: 1