Implement exact match expression builder for QRegularExpression

QRegularExpression doesn't offer a direct equivalent of QRegExp's exact
match.

There are several places in the Qt sources that use this feature. This
patch implements a small helper function that builds the expression as
recommended in the documentation and updates the related code.

[ChangeLog][Core][Tools] QRegularExpression now provides
anchoredPattern() which is a helper function to build regular
expressions used for exact matching.

Change-Id: Idbbf142c4c5cb9b62abf8229f4ce85fd4409e5d0
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Samuel Gaist 2018-07-25 09:23:28 +02:00
parent 6228c0528c
commit bcd80eebf9
6 changed files with 28 additions and 8 deletions

View File

@ -2129,7 +2129,7 @@ bool QDir::match(const QStringList &filters, const QString &fileName)
QString wildcard = QRegularExpression::wildcardToRegularExpression(*sit);
// Insensitive exact match
// (see Notes for QRegExp Users in QRegularExpression's documentation)
QRegularExpression rx(QLatin1String("\\A(?:") + wildcard + QLatin1String(")\\z"),
QRegularExpression rx(QRegularExpression::anchoredPattern(wildcard),
QRegularExpression::CaseInsensitiveOption);
if (rx.match(fileName).hasMatch())
return true;

View File

@ -483,6 +483,11 @@ QT_BEGIN_NAMESPACE
Note the usage of the non-capturing group in order to preserve the meaning
of the branch operator inside the pattern.
The QRegularExpression::anchoredPattern() helper method does exactly that for
you.
\sa anchoredPattern
\section3 Porting from QRegExp's Partial Matching
When using QRegExp::exactMatch(), if an exact match was not found, one
@ -1994,6 +1999,17 @@ QString QRegularExpression::wildcardToRegularExpression(const QString &pattern)
return rx;
}
/*!
\fn QRegularExpression::anchoredPattern(const QString &expression)
\since 5.12
Returns the expression wrapped between the \c{\A} and \c{\z} anchors to be
used for exact matching.
\sa {Porting from QRegExp's Exact Matching}
*/
/*!
\since 5.1

View File

@ -142,6 +142,12 @@ public:
static QString escape(const QString &str);
static QString wildcardToRegularExpression(const QString &str);
static inline QString anchoredPattern(const QString &expression)
{
return QLatin1String("\\A(?:")
+ expression
+ QLatin1String(")\\z");
}
bool operator==(const QRegularExpression &re) const;
inline bool operator!=(const QRegularExpression &re) const { return !operator==(re); }

View File

@ -692,7 +692,7 @@ int QtPrivate::QStringList_indexOf(const QStringList *that, const QRegularExpres
if (from < 0)
from = qMax(from + that->size(), 0);
QString exactPattern = QLatin1String("\\A(?:") + re.pattern() + QLatin1String(")\\z");
QString exactPattern = QRegularExpression::anchoredPattern(re.pattern());
QRegularExpression exactRe(exactPattern, re.patternOptions());
for (int i = from; i < that->size(); ++i) {
@ -722,7 +722,7 @@ int QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QRegularEx
else if (from >= that->size())
from = that->size() - 1;
QString exactPattern = QLatin1String("\\A(?:") + re.pattern() + QLatin1String(")\\z");
QString exactPattern = QRegularExpression::anchoredPattern(re.pattern());
QRegularExpression exactRe(exactPattern, re.patternOptions());
for (int i = from; i >= 0; --i) {

View File

@ -1079,7 +1079,7 @@ void QRegularExpressionValidatorPrivate::setRegularExpression(const QRegularExpr
if (origRe != re) {
usedRe = origRe = re; // copies also the pattern options
usedRe.setPattern(QLatin1String("\\A(?:") + re.pattern() + QLatin1String(")\\z"));
usedRe.setPattern(QRegularExpression::anchoredPattern(re.pattern()));
emit q->regularExpressionChanged(re);
emit q->changed();
}

View File

@ -2032,10 +2032,8 @@ bool QFileSystemModelPrivate::passNameFilters(const QFileSystemNode *node) const
: QRegularExpression::CaseInsensitiveOption;
for (const auto &nameFilter : nameFilters) {
const QString wildcard = QLatin1String("\\A(?:")
+ QRegularExpression::wildcardToRegularExpression(nameFilter)
+ QLatin1String(")\\z");
QRegularExpression rx(wildcard, options);
const QString wildcard = QRegularExpression::wildcardToRegularExpression(nameFilter);
QRegularExpression rx(QRegularExpression::anchoredPattern(wildcard), options);
QRegularExpressionMatch match = rx.match(node->fileName);
if (match.hasMatch())
return true;