Skip to content

Commit a85b0bc

Browse files
committed
Add regexp_substr function for returning matched part of string against regex
1 parent c07b2cc commit a85b0bc

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<h3>regexp_substr() function</h3>
2+
Returns the portion of a string which matches a supplied regular expression.
3+
4+
<p><h4>Syntax</h4>
5+
regexp_substr(<i>string,regex</i>)</p>
6+
7+
<p><h4>Arguments</h4>
8+
<!-- List args for functions here-->
9+
<i> string</i> &rarr; is string. The input string.<br>
10+
<i> regex</i> &rarr; is string. The regular expression to match against. Backslash characters must be double escaped (eg "\\s" to match a white space character).<br>
11+
12+
<p><h4>Example</h4>
13+
<!-- Show example of function.-->
14+
regexp_substr('abc123','(\\d+)') &rarr; '123'</p>

src/core/qgsexpression.cpp

+27-1
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,31 @@ static QVariant fcnRegexpMatch( const QVariantList& values, QgsFeature* , QgsExp
521521
return QVariant( str.contains( re ) ? 1 : 0 );
522522
}
523523

524+
static QVariant fcnRegexpSubstr( const QVariantList& values, QgsFeature* , QgsExpression* parent )
525+
{
526+
QString str = getStringValue( values.at( 0 ), parent );
527+
QString regexp = getStringValue( values.at( 1 ), parent );
528+
529+
QRegExp re( regexp );
530+
if ( !re.isValid() )
531+
{
532+
parent->setEvalErrorString( QObject::tr( "Invalid regular expression '%1': %2" ).arg( regexp ).arg( re.errorString() ) );
533+
return QVariant();
534+
}
535+
536+
// extract substring
537+
re.indexIn( str );
538+
if ( re.captureCount() > 0 )
539+
{
540+
// return first capture
541+
return QVariant( re.capturedTexts()[0] );
542+
}
543+
else
544+
{
545+
return QVariant( "" );
546+
}
547+
}
548+
524549
static QVariant fcnSubstr( const QVariantList& values, QgsFeature* , QgsExpression* parent )
525550
{
526551
QString str = getStringValue( values.at( 0 ), parent );
@@ -1233,7 +1258,7 @@ const QStringList &QgsExpression::BuiltinFunctions()
12331258
<< "coalesce" << "regexp_match" << "$now" << "age" << "year"
12341259
<< "month" << "week" << "day" << "hour"
12351260
<< "minute" << "second" << "lower" << "upper"
1236-
<< "title" << "length" << "replace" << "regexp_replace"
1261+
<< "title" << "length" << "replace" << "regexp_replace" << "regexp_substr"
12371262
<< "substr" << "concat" << "strpos" << "left"
12381263
<< "right" << "rpad" << "lpad"
12391264
<< "format_number" << "format_date"
@@ -1294,6 +1319,7 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
12941319
<< new StaticFunction( "length", 1, fcnLength, QObject::tr( "String" ) )
12951320
<< new StaticFunction( "replace", 3, fcnReplace, QObject::tr( "String" ) )
12961321
<< new StaticFunction( "regexp_replace", 3, fcnRegexpReplace, QObject::tr( "String" ) )
1322+
<< new StaticFunction( "regexp_substr", 2, fcnRegexpSubstr, QObject::tr( "String" ) )
12971323
<< new StaticFunction( "substr", 3, fcnSubstr, QObject::tr( "String" ) )
12981324
<< new StaticFunction( "concat", -1, fcnConcat, QObject::tr( "String" ) )
12991325
<< new StaticFunction( "strpos", 2, fcnStrpos, QObject::tr( "String" ) )

tests/src/core/testqgsexpression.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ class TestQgsExpression: public QObject
274274
QTest::newRow( "regexp_replace invalid" ) << "regexp_replace('HeLLo','[[[', '-')" << true << QVariant();
275275
QTest::newRow( "substr" ) << "substr('HeLLo', 3,2)" << false << QVariant( "LL" );
276276
QTest::newRow( "substr outside" ) << "substr('HeLLo', -5,2)" << false << QVariant( "" );
277+
QTest::newRow( "regexp_substr" ) << "regexp_substr('abc123','(\\\\d+)')" << false << QVariant( "123" );
278+
QTest::newRow( "regexp_substr invalid" ) << "regexp_substr('abc123','([[[')" << true << QVariant();
277279
QTest::newRow( "strpos" ) << "strpos('Hello World','World')" << false << QVariant( 6 );
278280
QTest::newRow( "strpos outside" ) << "strpos('Hello World','blah')" << false << QVariant( -1 );
279281
QTest::newRow( "left" ) << "left('Hello World',5)" << false << QVariant( "Hello" );

0 commit comments

Comments
 (0)