Skip to content
Permalink
Browse files
[qt6][expression] Migrate away from QRegExp
  • Loading branch information
nirvn committed Jul 14, 2021
1 parent 89e126e commit 86fa201640632d4dad0aac3d260e33cfd0cc1851
Showing with 19 additions and 16 deletions.
  1. +5 −6 src/core/expression/qgsexpression.cpp
  2. +14 −10 src/core/expression/qgsexpressionnodeimpl.cpp
@@ -499,14 +499,13 @@ QSet<QString> QgsExpression::referencedVariables( const QString &text )
int index = 0;
while ( index < text.size() )
{
QRegExp rx = QRegExp( "\\[%([^\\]]+)%\\]" );

int pos = rx.indexIn( text, index );
if ( pos < 0 )
const thread_local QRegularExpression rx( "\\[%([^\\]]+)%\\]" );
const QRegularExpressionMatch match = rx.match( text );
if ( !match.hasMatch() )
break;

index = pos + rx.matchedLength();
QString to_replace = rx.cap( 1 ).trimmed();
index = match.capturedStart() + match.capturedLength();
QString to_replace = match.captured( 1 ).trimmed();

QgsExpression exp( to_replace );
variables.unite( exp.referencedVariables() );
@@ -531,39 +531,42 @@ QVariant QgsExpressionNodeBinaryOperator::evalNode( QgsExpression *parent, const
ENSURE_NO_EVAL_ERROR
QString regexp = QgsExpressionUtils::getStringValue( vR, parent );
ENSURE_NO_EVAL_ERROR
// TODO: cache QRegExp in case that regexp is a literal string (i.e. it will stay constant)
// TODO: cache QRegularExpression in case that regexp is a literal string (i.e. it will stay constant)
bool matches;
if ( mOp == boLike || mOp == boILike || mOp == boNotLike || mOp == boNotILike ) // change from LIKE syntax to regexp
{
QString esc_regexp = QRegExp::escape( regexp );
// recreate QRegExp::escape function behavior
const thread_local QRegularExpression escapeRx( QStringLiteral( "([^\\\\])([\\$\\(\\)\\*\\+\\.\\?\\[\\]\\^\\{\\|\\}])" ) );
QString esc_regexp = regexp;
esc_regexp.replace( escapeRx, QStringLiteral( "\\1\\\\2" ) );
// manage escape % and _
if ( esc_regexp.startsWith( '%' ) )
{
esc_regexp.replace( 0, 1, QStringLiteral( ".*" ) );
}
thread_local QRegExp rx1( QStringLiteral( "[^\\\\](%)" ) );
const thread_local QRegularExpression rx1( QStringLiteral( "[^\\\\](%)" ) );
int pos = 0;
while ( ( pos = rx1.indexIn( esc_regexp, pos ) ) != -1 )
while ( ( pos = esc_regexp.indexOf( rx1, pos ) ) != -1 )
{
esc_regexp.replace( pos + 1, 1, QStringLiteral( ".*" ) );
pos += 1;
}
thread_local QRegExp rx2( QStringLiteral( "\\\\%" ) );
const thread_local QRegularExpression rx2( QStringLiteral( "\\\\%" ) );
esc_regexp.replace( rx2, QStringLiteral( "%" ) );
if ( esc_regexp.startsWith( '_' ) )
{
esc_regexp.replace( 0, 1, QStringLiteral( "." ) );
}
thread_local QRegExp rx3( QStringLiteral( "[^\\\\](_)" ) );
const thread_local QRegularExpression rx3( QStringLiteral( "[^\\\\](_)" ) );
pos = 0;
while ( ( pos = rx3.indexIn( esc_regexp, pos ) ) != -1 )
while ( ( pos = esc_regexp.indexOf( rx3, pos ) ) != -1 )
{
esc_regexp.replace( pos + 1, 1, '.' );
pos += 1;
}
esc_regexp.replace( QLatin1String( "\\\\_" ), QLatin1String( "_" ) );

matches = QRegExp( esc_regexp, mOp == boLike || mOp == boNotLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( str );
matches = QRegularExpression( QRegularExpression::anchoredPattern( esc_regexp ), mOp == boLike || mOp == boNotLike ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption ).match( str ).hasMatch();
}
else
{
@@ -1479,8 +1482,9 @@ bool QgsExpressionNodeColumnRef::prepareNode( QgsExpression *parent, const QgsEx

QString QgsExpressionNodeColumnRef::dump() const
{
const thread_local QRegExp re( QStringLiteral( "^[A-Za-z_\x80-\xff][A-Za-z0-9_\x80-\xff]*$" ) );
return re.exactMatch( mName ) ? mName : QgsExpression::quotedColumnRef( mName );
const thread_local QRegularExpression re( QStringLiteral( "^[A-Za-z_\x80-\xff][A-Za-z0-9_\x80-\xff]*$" ) );
const QRegularExpressionMatch match = re.match( mName );
return match.hasMatch() ? mName : QgsExpression::quotedColumnRef( mName );
}

QSet<QString> QgsExpressionNodeColumnRef::referencedColumns() const

0 comments on commit 86fa201

Please sign in to comment.