Skip to content

Commit 6f82740

Browse files
committedOct 26, 2016
[expressions] Allow non-greedy regex by switching to QRegularExpression
1 parent 323c658 commit 6f82740

File tree

5 files changed

+13
-9
lines changed

5 files changed

+13
-9
lines changed
 

‎resources/function_help/json/regexp_match

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"type": "function",
44
"description": "Returns true if any part of a string matches the supplied regular expression.",
55
"arguments": [ {"arg":"input_string","description":"the string to test against the regular expression"},
6-
{"arg":"regex","description":"The regular expression to test against. Backslash characters must be double escaped (eg \"\\\\\\\\s\" to match a white space character). Non-greedy regular expressions are not supported."}
6+
{"arg":"regex","description":"The regular expression to test against. Backslash characters must be double escaped (eg \"\\\\\\\\s\" to match a white space character)."}
77
],
88
"examples": [ { "expression":"regexp_match('QGIS ROCKS','\\\\\\\\sROCKS')", "returns":"true"}]
99
}

‎resources/function_help/json/regexp_replace

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"type": "function",
44
"description": "Returns a string with the supplied regular expression replaced.",
55
"arguments": [ {"arg":"input_string","description":"the string to replace matches in"},
6-
{"arg":"regex","description":"The regular expression to replace. Backslash characters must be double escaped (eg \"\\\\\\\\s\" to match a white space character). Non-greedy regular expressions are not supported."},
6+
{"arg":"regex","description":"The regular expression to replace. Backslash characters must be double escaped (eg \"\\\\\\\\s\" to match a white space character)."},
77
{"arg":"replacement","description":"The string that will replace any matching occurrences of the supplied regular expression. Captured groups can be inserted into the replacement string using \\\\\\\\1, \\\\\\\\2, etc."}
88
],
99
"examples": [ { "expression":"regexp_replace('QGIS SHOULD ROCK','\\\\\\\\sSHOULD\\\\\\\\s',' DOES ')", "returns":"'QGIS DOES ROCK'"}]

‎resources/function_help/json/regexp_substr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"type": "function",
44
"description": "Returns the portion of a string which matches a supplied regular expression.",
55
"arguments": [ {"arg":"input_string","description":"the string to find matches in"},
6-
{"arg":"regex","description":"The regular expression to match against. Backslash characters must be double escaped (eg \"\\\\\\\\s\" to match a white space character). Non-greedy regular expressions are not supported."}
6+
{"arg":"regex","description":"The regular expression to match against. Backslash characters must be double escaped (eg \"\\\\\\\\s\" to match a white space character)."}
77
],
88
"examples": [ { "expression":"regexp_substr('abc123','(\\\\\\\\d+)')", "returns":"'123'"}]
99
}

‎src/core/qgsexpression.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@ static QVariant fcnRegexpReplace( const QVariantList& values, const QgsExpressio
12251225
QString regexp = getStringValue( values.at( 1 ), parent );
12261226
QString after = getStringValue( values.at( 2 ), parent );
12271227

1228-
QRegExp re( regexp );
1228+
QRegularExpression re( regexp );
12291229
if ( !re.isValid() )
12301230
{
12311231
parent->setEvalErrorString( QObject::tr( "Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
@@ -1239,7 +1239,7 @@ static QVariant fcnRegexpMatch( const QVariantList& values, const QgsExpressionC
12391239
QString str = getStringValue( values.at( 0 ), parent );
12401240
QString regexp = getStringValue( values.at( 1 ), parent );
12411241

1242-
QRegExp re( regexp );
1242+
QRegularExpression re( regexp );
12431243
if ( !re.isValid() )
12441244
{
12451245
parent->setEvalErrorString( QObject::tr( "Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
@@ -1253,19 +1253,19 @@ static QVariant fcnRegexpSubstr( const QVariantList& values, const QgsExpression
12531253
QString str = getStringValue( values.at( 0 ), parent );
12541254
QString regexp = getStringValue( values.at( 1 ), parent );
12551255

1256-
QRegExp re( regexp );
1256+
QRegularExpression re( regexp );
12571257
if ( !re.isValid() )
12581258
{
12591259
parent->setEvalErrorString( QObject::tr( "Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
12601260
return QVariant();
12611261
}
12621262

12631263
// extract substring
1264-
( void )re.indexIn( str );
1265-
if ( re.captureCount() > 0 )
1264+
QRegularExpressionMatch match = re.match( str );
1265+
if ( match.hasMatch() )
12661266
{
12671267
// return first capture
1268-
return QVariant( re.capturedTexts().at( 1 ) );
1268+
return QVariant( match.captured( 0 ) );
12691269
}
12701270
else
12711271
{

‎tests/src/core/testqgsexpression.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,10 +822,14 @@ class TestQgsExpression: public QObject
822822
QTest::newRow( "length" ) << "length('HeLLo')" << false << QVariant( 5 );
823823
QTest::newRow( "replace" ) << "replace('HeLLo', 'LL', 'xx')" << false << QVariant( "Hexxo" );
824824
QTest::newRow( "regexp_replace" ) << "regexp_replace('HeLLo','[eL]+', '-')" << false << QVariant( "H-o" );
825+
QTest::newRow( "regexp_replace greedy" ) << "regexp_replace('HeLLo','(?<=H).*L', '-')" << false << QVariant( "H-o" );
826+
QTest::newRow( "regexp_replace non greedy" ) << "regexp_replace('HeLLo','(?<=H).*?L', '-')" << false << QVariant( "H-Lo" );
827+
QTest::newRow( "regexp_replace cap group" ) << "regexp_replace('HeLLo','(eL)', 'x\\\\1x')" << false << QVariant( "HxeLxLo" );
825828
QTest::newRow( "regexp_replace invalid" ) << "regexp_replace('HeLLo','[[[', '-')" << true << QVariant();
826829
QTest::newRow( "substr" ) << "substr('HeLLo', 3,2)" << false << QVariant( "LL" );
827830
QTest::newRow( "substr outside" ) << "substr('HeLLo', -5,2)" << false << QVariant( "" );
828831
QTest::newRow( "regexp_substr" ) << "regexp_substr('abc123','(\\\\d+)')" << false << QVariant( "123" );
832+
QTest::newRow( "regexp_substr non-greedy" ) << "regexp_substr('abc123','(\\\\d+?)')" << false << QVariant( "1" );
829833
QTest::newRow( "regexp_substr no hit" ) << "regexp_substr('abcdef','(\\\\d+)')" << false << QVariant( "" );
830834
QTest::newRow( "regexp_substr invalid" ) << "regexp_substr('abc123','([[[')" << true << QVariant();
831835
QTest::newRow( "strpos" ) << "strpos('Hello World','World')" << false << QVariant( 7 );

1 commit comments

Comments
 (1)

nirvn commented on Oct 26, 2016

@nirvn
Contributor

nice.

Please sign in to comment.