PDA

View Full Version : qregexp can't get match 'not preceeded by' to work



kja
25th July 2011, 01:49
Hi I can't figure out the regex to match any number not preceded by '['

I don't know why this doesn't work:

QRegExp n( "(?![)[0-9]+" );

I could also get the match I want by searching for a number not followed by ']' but I can't get that regex to work either:

QRegExp n( "[0-9]+(?!])" );

I have tried many variations of this, including escaping the ]'s like this --> "(?!\\])" --- but i can't get my match.

Just to be clear I want to match 150 but not [150].

Also, I would use "[^[]" but that would not match a number at the very beginning of the line.

What am I missing?
Thanks.

NortT
25th July 2011, 04:42
Hi, try this code:


QRegExp rx1("\\[(\\d+)\\]");
QString str = "Some text [12] and [14] numbers 99 [231] 7";
QStringList list;
int pos = 0;

while ((pos = rx1.indexIn(str, pos)) != -1)
{
list << rx1.cap(1);
pos += rx1.matchedLength();
}

for (int i=0; i<list.size(); i++)
{
qDebug()<<list[i];
}
In console output you get:
"12"
"14"
"231"

--
Sorry for my bad English :)

kja
25th July 2011, 16:32
Thanks for your help, I realized I was not clear with my question. To use your example

QString str = "Some text [12] and [14] numbers 99 [231] 7";

I would only want to match 99 and 7, not any of the numbers within the brackets.

I want to figure out how to use the 'not preceded by' or 'not followed by' regexp's

The QregExp documentation (http://doc.qt.nokia.com/latest/qregexp.html) talks about negative lookahead syntax but the same doesn't seem to work for looking behind, but I have gotten a little closer:

QRegExp n("[0-9]+(?!\\])");

string = "blah [10] 24"
matches 1 and 24.

This matches the '1' in the [10], which I don't want, but (?!\\[) put in front does not work...

any ideas?





Thanks.

ChrisW67
25th July 2011, 23:44
The QRegExp docs talk about look behind assertions:

Both zero-width positive and zero-width negative lookahead assertions (?=pattern) and (?!pattern) are supported with the same syntax as Perl. Perl's lookbehind assertions, "independent" subexpressions and conditional expressions are not supported.This the subject of a few bug reports.

bst
27th July 2011, 08:35
Hi,

the RegExp machine always tries to make a match.

In "blah [10] 24" the "[0-9]+" matches the "1" and the "(?!\\])" matches the "0".
This is correct because "0" is not "]".

To prevent the RE here to match the "0" you either need a possessive quantifier (like (?>) in Perl or ++ in Java, but sadly not available in QRegExp) or you also need to exclude the digits in your lookahead. Use "(?![]0-9])" here.

Because there also exists no lookbehind you need a "[^[0-9]" to exclude a leading "[". To also match at the beginning of the string you need to add a "^|" in the beginning.

Note that now the character before the 'wanted match' is part of the match itself, e.g. you get " 99", not only "99".

Where required capture the digits using () and use .cap(1).

HTH, Bernd
--

int main(void)
{
QString str = "Some text [12] and [14] numbers 99 [231] 7";
QRegExp rx("(?:^|[^[0-9])([0-9]+)(?![]0-9])");

int pos = 0;
while ((pos = rx.indexIn(str, pos)) != -1)
{
qDebug() << rx.cap(1);
pos += rx.matchedLength();
}
}