mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-04 00:04:03 -04:00
add count_substring expression
This commit is contained in:
parent
762c57032b
commit
0936526ba7
57
resources/function_help/json/substr_count
Normal file
57
resources/function_help/json/substr_count
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "substr_count",
|
||||
"type": "function",
|
||||
"groups": [
|
||||
"String"
|
||||
],
|
||||
"description": "Counts the number of occurrences of a substring within a string. By default, the function counts non-overlapping occurrences (like in Python). If the third argument is set to true, the function counts overlapping occurrences (like in QT).",
|
||||
"arguments": [
|
||||
{
|
||||
"arg": "input",
|
||||
"description": "The input string to search in."
|
||||
},
|
||||
{
|
||||
"arg": "substring",
|
||||
"description": "The substring to search for."
|
||||
},
|
||||
{
|
||||
"arg": "overlapping",
|
||||
"description": "Optional flag to control whether overlapping occurrences should be counted. Defaults to false (non-overlapping counting). Set to true to count overlapping occurrences."
|
||||
}
|
||||
],
|
||||
"examples": [
|
||||
{
|
||||
"expression": "substr_count('banana', 'an')",
|
||||
"returns": "2",
|
||||
"description": "Counts non-overlapping occurrences of 'an' in 'banana'."
|
||||
},
|
||||
{
|
||||
"expression": "substr_count('Funniness', 'n')",
|
||||
"returns": "3",
|
||||
"description": "Counts non-overlapping occurrences of 'n' in 'Funniness'."
|
||||
},
|
||||
{
|
||||
"expression": "substr_count('aaaaa', 'aa')",
|
||||
"returns": "2",
|
||||
"description": "Counts non-overlapping occurrences of 'aa' in 'aaaaa'."
|
||||
},
|
||||
{
|
||||
"expression": "substr_count('aaaaa', 'aa', true)",
|
||||
"returns": "4",
|
||||
"description": "Counts overlapping occurrences of 'aa' in 'aaaaa'. The substring 'aa' appears four times in an overlapping fashion."
|
||||
},
|
||||
{
|
||||
"expression": "substr_count('BANANA', 'an')",
|
||||
"returns": "0",
|
||||
"description": "Counts non-overlapping occurrences of 'an' in 'BANANA'. Case-sensitive, so no match."
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"text",
|
||||
"find",
|
||||
"string",
|
||||
"substring",
|
||||
"count",
|
||||
"occurrence"
|
||||
]
|
||||
}
|
@ -2698,6 +2698,41 @@ static QVariant fcnRight( const QVariantList &values, const QgsExpressionContext
|
||||
return string.right( pos );
|
||||
}
|
||||
|
||||
static QVariant fcnSubstrCount( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
if ( values.length() < 2 || values.length() > 3 )
|
||||
return QVariant();
|
||||
|
||||
const QString input = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
|
||||
const QString substring = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
|
||||
|
||||
bool overlapping = false;
|
||||
if ( values.length() == 3 )
|
||||
{
|
||||
overlapping = values.at( 2 ).toBool();
|
||||
}
|
||||
|
||||
if ( substring.isEmpty() )
|
||||
return QVariant( 0 );
|
||||
|
||||
int count = 0;
|
||||
if ( overlapping )
|
||||
{
|
||||
count = input.count( substring );
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos = 0;
|
||||
while ( ( pos = input.indexOf( substring, pos ) ) != -1 )
|
||||
{
|
||||
count++;
|
||||
pos += substring.length();
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant( count );
|
||||
}
|
||||
|
||||
static QVariant fcnLeft( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
QString string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
|
||||
@ -8714,6 +8749,12 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "set_timezone" ), { QgsExpressionFunction::Parameter( QStringLiteral( "datetime" ) ), QgsExpressionFunction::Parameter( QStringLiteral( "timezone" ) ) }, fcnSetTimeZone, QStringLiteral( "Date and Time" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "convert_timezone" ), { QgsExpressionFunction::Parameter( QStringLiteral( "datetime" ) ), QgsExpressionFunction::Parameter( QStringLiteral( "timezone" ) ) }, fcnConvertTimeZone, QStringLiteral( "Date and Time" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "lower" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnLower, QStringLiteral( "String" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "substr_count" ), QgsExpressionFunction::ParameterList()
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "input" ) )
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "substring" ) )
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "overlapping" ), true, false ), // Optional parameter with default value of false
|
||||
fcnSubstrCount,
|
||||
QStringLiteral( "String" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "upper" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnUpper, QStringLiteral( "String" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "title" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnTitle, QStringLiteral( "String" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "trim" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnTrim, QStringLiteral( "String" ) )
|
||||
|
@ -1841,6 +1841,12 @@ class TestQgsExpression : public QObject
|
||||
QTest::newRow( "regexp_replace non greedy" ) << "regexp_replace('HeLLo','(?<=H).*?L', '-')" << false << QVariant( "H-Lo" );
|
||||
QTest::newRow( "regexp_replace cap group" ) << "regexp_replace('HeLLo','(eL)', 'x\\\\1x')" << false << QVariant( "HxeLxLo" );
|
||||
QTest::newRow( "regexp_replace invalid" ) << "regexp_replace('HeLLo','[[[', '-')" << true << QVariant();
|
||||
QTest::newRow( "substr_count basic" ) << "substr_count('banana', 'an')" << false << QVariant( 2 );
|
||||
QTest::newRow( "substr_count basic funny" ) << "substr_count('Funniness', 'n')" << false << QVariant( 3 );
|
||||
QTest::newRow( "substr_count non-overlapping counted" ) << "substr_count('aaaaa', 'aa')" << false << QVariant( 2 );
|
||||
QTest::newRow( "substr_count overlapping counted" ) << "substr_count('aaaaa', 'aa', true)" << false << QVariant( 4 );
|
||||
QTest::newRow( "substr_count empty needle" ) << "substr_count('abc', '')" << false << QVariant( 0 );
|
||||
QTest::newRow( "substr_count case sensitivity" ) << "substr_count('BANANA', 'an')" << false << QVariant( 0 );
|
||||
QTest::newRow( "reverse string" ) << "reverse('HeLLo')" << false << QVariant( "oLLeH" );
|
||||
QTest::newRow( "reverse empty string" ) << "reverse('')" << false << QVariant( "" );
|
||||
QTest::newRow( "substr" ) << "substr('HeLLo', 3,2)" << false << QVariant( "LL" );
|
||||
|
Loading…
x
Reference in New Issue
Block a user