summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Gaist <samuel.gaist@idiap.ch>2018-08-01 00:07:11 +0200
committerSamuel Gaist <samuel.gaist@idiap.ch>2018-08-16 16:30:14 +0000
commit30b0701c9b50ec718ec858d7777a01c66e333a9c (patch)
tree21f5eb38257aaa50ab18b4ae9d1e644170f8efbe
parent0f6b941ca54f9714627b8d5a94be163dc02126c1 (diff)
Refactor wildcard support in QRegularExpression
The API originally proposed was flawed in the sense that the setter function would use a modified version of the parameter given which would have make it a black box for the user. This patch fixes that by removing that setter and providing a static method that will return the pattern suitably modified to be used by QRegularExpression the same way the escape method does. [ChangeLog][Core][QRegularExpression] Implemented support for wildcard patterns through a static method. Change-Id: I0054bcaffd7525dac569f54fa81f73b7e4544b2e Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp7
-rw-r--r--src/corelib/tools/qregularexpression.cpp238
-rw-r--r--src/corelib/tools/qregularexpression.h2
-rw-r--r--src/corelib/tools/qregularexpression_p.h70
-rw-r--r--src/corelib/tools/tools.pri3
-rw-r--r--tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp14
6 files changed, 133 insertions, 201 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp
index 5f0a175374..28c66628b7 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp
@@ -350,4 +350,11 @@ while (i.hasNext()) {
//! [30]
}
+{
+//! [31]
+QString wildcard = QRegularExpression::wildcardToRegularExpression("*.jpeg");
+// wilcard == ".*\.jpeg"
+//! [31]
+}
+
}
diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp
index af2e46dd00..17caaabc97 100644
--- a/src/corelib/tools/qregularexpression.cpp
+++ b/src/corelib/tools/qregularexpression.cpp
@@ -516,10 +516,10 @@ QT_BEGIN_NAMESPACE
\section2 Wildcard matching
- There is no equivalent of wildcard matching in QRegularExpression.
- Nevertheless, rewriting a regular expression in wildcard syntax to a
- Perl-compatible regular expression is a very easy task, given the fact
- that wildcard syntax supported by QRegExp is very simple.
+ There is no direct way to do wildcard matching in QRegularExpression.
+ However, the wildcardToRegularExpression method is provided to translate
+ glob patterns into a Perl-compatible regular expression that can be used
+ for that purpose.
\section2 Other pattern syntaxes
@@ -784,82 +784,6 @@ QT_BEGIN_NAMESPACE
Qt 5.4.
*/
-namespace QtPrivate {
-/*!
- internal
-*/
-QString wildcardToRegularExpression(const QString &wildcardString)
-{
- const int wclen = wildcardString.length();
- QString rx;
- int i = 0;
- bool hasNegativeBracket = false;
- const QChar *wc = wildcardString.unicode();
-
- while (i < wclen) {
- const QChar c = wc[i++];
- switch (c.unicode()) {
- case '*':
- rx += QLatin1String(".*");
- break;
- case '?':
- rx += QLatin1Char('.');
- break;
- case '$':
- case '(':
- case ')':
- case '+':
- case '.':
- case '^':
- case '{':
- case '|':
- case '}':
- rx += QLatin1Char('\\');
- rx += c;
- break;
- case '[':
- // Support for the [!abc] or [!a-c] syntax
- // Implements a negative look-behind for one char.
- if (wc[i] == QLatin1Char(']')) {
- rx += c;
- rx += wc[i++];
- } else if (wc[i] == QLatin1Char('!')) {
- rx += QLatin1String(".(?<");
- rx += wc[i++];
- rx += c;
- hasNegativeBracket = true;
- } else {
- rx += c;
- }
-
- if (i < wclen) {
- if (rx[i] == QLatin1Char(']'))
- rx += wc[i++];
- while (i < wclen && wc[i] != QLatin1Char(']')) {
- if (wc[i] == QLatin1Char('\\'))
- rx += QLatin1Char('\\');
- rx += wc[i++];
- }
- }
- break;
- case ']':
- rx += c;
- // Closes the negative look-behind expression.
- if (hasNegativeBracket) {
- rx += QLatin1Char(')');
- hasNegativeBracket = false;
- }
- break;
- default:
- rx += c;
- break;
- }
- }
-
- return rx;
-}
-}
-
/*!
\internal
*/
@@ -1583,47 +1507,6 @@ void QRegularExpression::setPattern(const QString &pattern)
}
/*!
- \since 5.12
-
- Sets the pattern string of the regular expression to \a wildcard pattern.
- The pattern options are left unchanged.
-
- \warning Unlike QRegExp, this implementation follows closely the definition
- of wildcard for glob patterns:
- \table
- \row \li \b{c}
- \li Any character represents itself apart from those mentioned
- below. Thus \b{c} matches the character \e c.
- \row \li \b{?}
- \li Matches any single character. It is the same as
- \b{.} in full regexps.
- \row \li \b{*}
- \li Matches zero or more of any characters. It is the
- same as \b{.*} in full regexps.
- \row \li \b{[abc]}
- \li Matches one character given in the bracket.
- \row \li \b{[a-c]}
- \li Matches one character from the range given in the bracket.
- \row \li \b{[!abc]}
- \li Matches one character that is not given in the bracket.
- \row \li \b{[!a-c]}
- \li matches one character that is not from the range given in the
- bracket.
- \endtable
-
- \note This function generates a regular expression that will act following
- the wildcard pattern given. However the content of the regular expression
- will not be the same as the one set.
-
- \sa pattern(), setPattern()
-*/
-void QRegularExpression::setWildcardPattern(const QString &pattern)
-{
- setPattern(QtPrivate::wildcardToRegularExpression(pattern));
-}
-
-
-/*!
Returns the pattern options for the regular expression.
\sa setPatternOptions(), pattern()
@@ -1988,6 +1871,119 @@ QString QRegularExpression::escape(const QString &str)
}
/*!
+ \since 5.12
+
+ Returns a regular expression representation of the given glob \a pattern.
+
+ \snippet code/src_corelib_tools_qregularexpression.cpp 31
+
+ \warning Unlike QRegExp, this implementation follows closely the definition
+ of wildcard for glob patterns:
+ \table
+ \row \li \b{c}
+ \li Any character represents itself apart from those mentioned
+ below. Thus \b{c} matches the character \e c.
+ \row \li \b{?}
+ \li Matches any single character. It is the same as
+ \b{.} in full regexps.
+ \row \li \b{*}
+ \li Matches zero or more of any characters. It is the
+ same as \b{.*} in full regexps.
+ \row \li \b{[abc]}
+ \li Matches one character given in the bracket.
+ \row \li \b{[a-c]}
+ \li Matches one character from the range given in the bracket.
+ \row \li \b{[!abc]}
+ \li Matches one character that is not given in the bracket. It is the
+ same as \b{[^abc]} in full regexp.
+ \row \li \b{[!a-c]}
+ \li Matches one character that is not from the range given in the
+ bracket. It is the same as \b{[^a-c]} in full regexp.
+ \endtable
+
+ \note The backslash (\\) character is \e not an escape char in this context.
+ In order to match one of the special characters, place it in square brackets
+ (for example, "[?]").
+
+ More information about the implementation can be found in:
+ \list
+ \li \l {https://en.wikipedia.org/wiki/Glob_(programming)} {The Wikipedia Glob article}
+ \li \c man 7 glob
+ \endlist
+
+ \sa escape()
+*/
+QString QRegularExpression::wildcardToRegularExpression(const QString &pattern)
+{
+ const int wclen = pattern.length();
+ QString rx;
+ int i = 0;
+ bool hasNegativeBracket = false;
+ const QChar *wc = pattern.unicode();
+
+ while (i < wclen) {
+ const QChar c = wc[i++];
+ switch (c.unicode()) {
+ case '*':
+ rx += QLatin1String(".*");
+ break;
+ case '?':
+ rx += QLatin1Char('.');
+ break;
+ case '$':
+ case '(':
+ case ')':
+ case '+':
+ case '.':
+ case '^':
+ case '{':
+ case '|':
+ case '}':
+ rx += QLatin1Char('\\');
+ rx += c;
+ break;
+ case '[':
+ // Support for the [!abc] or [!a-c] syntax
+ // Implements a negative look-behind for one char.
+ if (i < wclen) {
+ if (wc[i] == QLatin1Char(']')) {
+ rx += c;
+ rx += wc[i++];
+ } else if (wc[i] == QLatin1Char('!')) {
+ rx += QLatin1String(".(?<");
+ rx += wc[i++];
+ rx += c;
+ hasNegativeBracket = true;
+ } else {
+ rx += c;
+ }
+ while (i < wclen && wc[i] != QLatin1Char(']')) {
+ if (wc[i] == QLatin1Char('\\'))
+ rx += QLatin1Char('\\');
+ rx += wc[i++];
+ }
+ } else {
+ rx += c;
+ }
+ break;
+ case ']':
+ rx += c;
+ // Closes the negative look-behind expression.
+ if (hasNegativeBracket) {
+ rx += QLatin1Char(')');
+ hasNegativeBracket = false;
+ }
+ break;
+ default:
+ rx += c;
+ break;
+ }
+ }
+
+ return rx;
+}
+
+/*!
\since 5.1
Constructs a valid, empty QRegularExpressionMatch object. The regular
diff --git a/src/corelib/tools/qregularexpression.h b/src/corelib/tools/qregularexpression.h
index d0f90b90b3..388aa7a8ca 100644
--- a/src/corelib/tools/qregularexpression.h
+++ b/src/corelib/tools/qregularexpression.h
@@ -96,7 +96,6 @@ public:
QString pattern() const;
void setPattern(const QString &pattern);
- void setWildcardPattern(const QString &pattern);
bool isValid() const;
int patternErrorOffset() const;
@@ -142,6 +141,7 @@ public:
void optimize() const;
static QString escape(const QString &str);
+ static QString wildcardToRegularExpression(const QString &str);
bool operator==(const QRegularExpression &re) const;
inline bool operator!=(const QRegularExpression &re) const { return !operator==(re); }
diff --git a/src/corelib/tools/qregularexpression_p.h b/src/corelib/tools/qregularexpression_p.h
deleted file mode 100644
index f5455de853..0000000000
--- a/src/corelib/tools/qregularexpression_p.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 Samuel Gaist <samuel.gaist@edeltech.ch>
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QREGULAREXPRESSION_P_H
-#define QREGULAREXPRESSION_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qglobal_p.h>
-
-#include <qregularexpression.h>
-#include <qstring.h>
-
-QT_REQUIRE_CONFIG(regularexpression);
-
-QT_BEGIN_NAMESPACE
-
-namespace QtPrivate {
-QString wildcardToRegularExpression(const QString &expression);
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 7a74dfda3e..9ec6ea4894 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -183,8 +183,7 @@ qtConfig(regularexpression) {
QMAKE_USE_PRIVATE += pcre2
HEADERS += \
- tools/qregularexpression.h \
- tools/qregularexpression_p.h
+ tools/qregularexpression.h
SOURCES += tools/qregularexpression.cpp
}
diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
index 5130b7cfcd..987ca519ee 100644
--- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
+++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
@@ -2171,6 +2171,10 @@ void tst_QRegularExpression::wildcard_data()
addRow(".???l", "test.html", 4);
addRow("?", "test.html", 0);
addRow("?m", "test.html", 6);
+ addRow("[*]", "test.html", -1);
+ addRow("[?]","test.html", -1);
+ addRow("[[]","test.h[ml", 6);
+ addRow("[]]","test.h]ml", 6);
addRow(".h[a-z]ml", "test.html", 4);
addRow(".h[A-Z]ml", "test.html", -1);
addRow(".h[A-Z]ml", "test.hTml", 4);
@@ -2191,9 +2195,7 @@ void tst_QRegularExpression::wildcard()
QFETCH(QString, string);
QFETCH(int, foundIndex);
- QRegularExpression re;
- re.setWildcardPattern(pattern);
-
+ QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern));
QRegularExpressionMatch match = re.match(string);
QCOMPARE(match.capturedStart(), foundIndex);
@@ -2217,11 +2219,9 @@ void tst_QRegularExpression::testInvalidWildcard_data()
void tst_QRegularExpression::testInvalidWildcard()
{
QFETCH(QString, pattern);
-
- QRegularExpression re;
- re.setWildcardPattern(pattern);
-
QFETCH(bool, isValid);
+
+ QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern));
QCOMPARE(re.isValid(), isValid);
}