PDA

View Full Version : QReqExp for (v1=vlaue1 v2 = value2 v3= value3 )



jesse_mark
20th November 2012, 20:19
Hello Guys,

I need help for ReqExp for parse one line e.x

string {any number of spaces} = String {any unmber of spaces} String = string)
just like

QString line = "v1=vlaue1 v2 = value2 v3= value3"

I need to split this QString to get QStringList of pairs of the variable and its value such as :

QStringList tmp;
tmp = line.split(ReqExp(....) )

/*the resulted tmp will be like :
tmp[0]= "v1=vlaue1"
tmp[1]= "v2 = value2"
tmp[2]= "v3= value3"
*/

so please could you help me with the ReqExp so i can use it with the split function.

PS: the line could has only one pair(v1=vlaue1) or maybe more (v1=vlaue1 .................vn=vlauen).


Thank you in advance.

Added after 50 minutes:

I though it could be something like this

QRegExp("//s*//w*//s*=//s*//w*")

but this does not work with me, im sure im not doing the expression correct any help will be appreciated

amleto
20th November 2012, 20:51
how about just use split with separators = and space??

If you're gonna use regex, at least use the correct slash :rolleyes:

Oh yea, if you use split(regex), then the bit you capture with regex will get thrown away! Same as if you did split(",") - you don't want to keep the ",", you want to split on it!



QString line = " v1 = 1 v2 = 2 v3=three ";

QString line2 = line.replace("=", " ");
QStringList qsl = line.split(" ", QString::SkipEmptyParts);



If you want to use regex, then indexIn(), and matchedLength() would need to be used.


QRegExp re("\\s*\\w*\\s*=\\s*\\w*\\s*");
QString line = " v1 = 1 v2 = 2 v3=three ";
int i0 = re.indexIn(line);
int i1 = re.matchedLength();
int i2 = re.lastIndexIn(line);
int i3 = re.matchedLength();

ChrisW67
20th November 2012, 21:28
The pattern used by split() is supposed to match the delimiters, not the bits you want to keep. You would need the pattern to match any number of spaces not preceded or followed by an '='. I think this would be tricky without look-behind assertions (not supported in QRegExp).

You could use amleto's suggestion to get a list of "words" and then reconstitute the pairs.

Or, don't try to split the string; deliberately extract the matching parts (straight from the docs):


QString line = "v1=vlaue1 v2 = value2 v3= value3";

QRegExp re("\\w+\\s*=\\s*\\w+");
QStringList result;
int pos = 0;
while ((pos = re.indexIn(line, pos)) != -1) {
result << re.cap(0);
pos += re.matchedLength();
}
qDebug() << result;
// ("v1=vlaue1", "v2 = value2", "v3= value3")

This assumes the name and value cannot themselves contain spaces or '='.

jesse_mark
20th November 2012, 21:53
Thank you so much for the the idea and helping with code.

which way do you recommend me to use ??

amleto
20th November 2012, 22:26
personally, I don't see the benefit from using regex here so I would avoid it.

ChrisW67
20th November 2012, 22:54
which way do you recommend me to use ??
As always, one that works for you. My option gives you what you asked for (and handles any number of name/value pairs) but I do not know what you are ultimately going to do with the elements in the string list. If you are only going to later split them on the '=' then the replace/split approach in Amleto's post gets you there faster. If you must preserve the uneven spacing around '=' then you cannot use replace/split approach.

jesse_mark
21st November 2012, 15:45
Thank you so much for your suggestions.

I used both the regexp and the replace/split.
I used to the regexp just to make sure the line has the format that i expect it and the replace/split to do the parsing.

jesse_mark
21st November 2012, 20:22
I faced an issue now, when using both ways.

f.e. is
line = "V1= V2=x V3 = y"
if one of the variables were missing its value, the both ways gave me wrong result. :(

amleto
21st November 2012, 20:40
surely that does not count as a 'valid' line?

jesse_mark
21st November 2012, 20:56
Yeah, but how can I validate it ??

ChrisW67
21st November 2012, 21:37
line = "V1= V2=x V3 = y"
if one of the variables were missing its value, the both ways gave me wrong result. :(
Why of course, Sir, here's what you specified:


string {any number of spaces} = String {any unmber of spaces} String = string)

with no mention of the possibility of empty strings.

With your new input how is the expression supposed to know that V2 is the name of a second variable and not the value of the first? You might say, "but it's followed by an equal sign, and that makes it a name" That is not an adequate description because you allow space between the name and the '=' e.g. if the line was:


V1= V2 = x V3 = y

A naïve attempt using my base regexp:


QString line = "v1= v2 = value2 v3= value3";
QRegExp re("\\w+\\s*=\\s*\\w*(?!\\s+=)");
// ("v1= v", "2 = value2", "v3= value3")

fails in new and unexpected ways. This comes closer:


QRegExp re("(\\w+\\s*=\\s*\\w*)\\s(?!\\s*=)");
QStringList result;
int pos = 0;
while ((pos = re.indexIn(line, pos)) != -1) {
result << re.cap(1);
pos += re.matchedLength();
}
qDebug() << result;
// ("v1=", "v2 = value2", "v3=")

but I can almost guarantee that it will fail for some other input.

Parsing dirty data is not trivial. Often the only way is to pull the text apart and code the rules and exceptions.