diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2020-12-02 12:31:41 +0100 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2020-12-10 02:15:18 +0100 |
commit | ce0b76731042412a0fa5a5f633fc48a52f79ef81 (patch) | |
tree | b0e697beba8c24158a6312341417b82b6a561d2c /src | |
parent | be83ff65c424cff1036e7da19d6175826d9f7ed9 (diff) |
QStringView: add some QRegularExpression-related overloads
[ChangeLog][QtCore][QStringView] Added the indexOf(), contains(),
lastIndexOf() and count() methods taking a QRegularExpression.
Fixes: QTBUG-89050
Change-Id: Ic726754f67e06b3764302d2fad252e0378a77afc
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/text/qstring.cpp | 78 | ||||
-rw-r--r-- | src/corelib/text/qstringalgorithms.h | 17 | ||||
-rw-r--r-- | src/corelib/text/qstringview.cpp | 61 | ||||
-rw-r--r-- | src/corelib/text/qstringview.h | 20 |
4 files changed, 176 insertions, 0 deletions
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 92eed93251..07b8c8512b 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -10259,6 +10259,84 @@ qsizetype QtPrivate::lastIndexOf(QLatin1String haystack, qsizetype from, QLatin1 return qLastIndexOf(haystack, from, needle, cs); } +#if QT_CONFIG(regularexpression) +qsizetype QtPrivate::indexOf(QStringView haystack, const QRegularExpression &re, qsizetype from, QRegularExpressionMatch *rmatch) +{ + if (!re.isValid()) { + qWarning("QStringView::indexOf: invalid QRegularExpression object"); + return -1; + } + + QRegularExpressionMatch match = re.match(haystack, from); + if (match.hasMatch()) { + const qsizetype ret = match.capturedStart(); + if (rmatch) + *rmatch = std::move(match); + return ret; + } + + return -1; +} + +qsizetype QtPrivate::lastIndexOf(QStringView haystack, const QRegularExpression &re, qsizetype from, QRegularExpressionMatch *rmatch) +{ + if (!re.isValid()) { + qWarning("QStringView::lastIndexOf: invalid QRegularExpression object"); + return -1; + } + + qsizetype endpos = (from < 0) ? (haystack.size() + from + 1) : (from); + QRegularExpressionMatchIterator iterator = re.globalMatch(haystack); + qsizetype lastIndex = -1; + while (iterator.hasNext()) { + QRegularExpressionMatch match = iterator.next(); + qsizetype start = match.capturedStart(); + if (start <= endpos) { + lastIndex = start; + if (rmatch) + *rmatch = std::move(match); + } else { + break; + } + } + + return lastIndex; +} + +bool QtPrivate::contains(QStringView haystack, const QRegularExpression &re, QRegularExpressionMatch *rmatch) +{ + if (!re.isValid()) { + qWarning("QStringView::contains: invalid QRegularExpression object"); + return false; + } + QRegularExpressionMatch m = re.match(haystack); + bool hasMatch = m.hasMatch(); + if (hasMatch && rmatch) + *rmatch = std::move(m); + return hasMatch; +} + +qsizetype QtPrivate::count(QStringView haystack, const QRegularExpression &re) +{ + if (!re.isValid()) { + qWarning("QStringView::count: invalid QRegularExpression object"); + return 0; + } + qsizetype count = 0; + qsizetype index = -1; + qsizetype len = haystack.length(); + while (index <= len - 1) { + QRegularExpressionMatch match = re.match(haystack, index + 1); + if (!match.hasMatch()) + break; + index = match.capturedStart(); + count++; + } + return count; +} + +#endif // QT_CONFIG(regularexpression) + /*! \since 5.0 diff --git a/src/corelib/text/qstringalgorithms.h b/src/corelib/text/qstringalgorithms.h index 6d8fe114f1..870ae42af8 100644 --- a/src/corelib/text/qstringalgorithms.h +++ b/src/corelib/text/qstringalgorithms.h @@ -70,6 +70,8 @@ class QStringView; template <bool> class QBasicUtf8StringView; class QAnyStringView; class QChar; +class QRegularExpression; +class QRegularExpressionMatch; namespace QtPrivate { @@ -122,6 +124,21 @@ namespace QtPrivate { [[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QStringView haystack, QChar needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept; [[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept; +#if QT_CONFIG(regularexpression) +[[nodiscard]] Q_CORE_EXPORT qsizetype indexOf(QStringView haystack, + const QRegularExpression &re, + qsizetype from = 0, + QRegularExpressionMatch *rmatch = nullptr); +[[nodiscard]] Q_CORE_EXPORT qsizetype lastIndexOf(QStringView haystack, + const QRegularExpression &re, + qsizetype from = -1, + QRegularExpressionMatch *rmatch = nullptr); +[[nodiscard]] Q_CORE_EXPORT bool contains(QStringView haystack, + const QRegularExpression &re, + QRegularExpressionMatch *rmatch = nullptr); +[[nodiscard]] Q_CORE_EXPORT qsizetype count(QStringView haystack, const QRegularExpression &re); +#endif + [[nodiscard]] Q_CORE_EXPORT QString convertToQString(QAnyStringView s); [[nodiscard]] Q_CORE_EXPORT QByteArray convertToLatin1(QStringView str); diff --git a/src/corelib/text/qstringview.cpp b/src/corelib/text/qstringview.cpp index 1b8db705b4..b64d128a65 100644 --- a/src/corelib/text/qstringview.cpp +++ b/src/corelib/text/qstringview.cpp @@ -881,6 +881,67 @@ QT_BEGIN_NAMESPACE \sa QString::lastIndexOf() */ +#if QT_CONFIG(regularexpression) +/*! + \fn qsizetype QStringView::indexOf(const QRegularExpression &re, qsizetype from, QRegularExpressionMatch *rmatch) const + \since 6.1 + + Returns the index position of the first match of the regular + expression \a re in the string view, searching forward from index + position \a from. Returns -1 if \a re didn't match anywhere. + + If the match is successful and \a rmatch is not \nullptr, it also + writes the results of the match into the QRegularExpressionMatch object + pointed to by \a rmatch. + + \note Due to how the regular expression matching algorithm works, + this function will actually match repeatedly from the beginning of + the string view until the position \a from is reached. +*/ + +/*! + \fn qsizetype QStringView::lastIndexOf(const QRegularExpression &re, qsizetype from, QRegularExpressionMatch *rmatch) const + \since 6.1 + + Returns the index position of the last match of the regular + expression \a re in the string view, which starts before the index + position \a from. Returns -1 if \a re didn't match anywhere. + + If the match is successful and \a rmatch is not \nullptr, it also + writes the results of the match into the QRegularExpressionMatch object + pointed to by \a rmatch. +*/ + +/*! + \fn bool QStringView::contains(const QRegularExpression &re, QRegularExpressionMatch *rmatch) const + \since 6.1 + + Returns \c true if the regular expression \a re matches somewhere in this + string view; otherwise returns \c false. + + If the match is successful and \a rmatch is not \nullptr, it also + writes the results of the match into the QRegularExpressionMatch object + pointed to by \a rmatch. + + \sa QRegularExpression::match() +*/ + +/*! + \fn qsizetype QStringView::count(const QRegularExpression &re) const + \since 6.1 + + Returns the number of times the regular expression \a re matches + in the string view. + + For historical reasons, this function counts overlapping matches. + This behavior is different from simply iterating over the matches + in the string using QRegularExpressionMatchIterator. + + \sa QRegularExpression::globalMatch() + +*/ +#endif // QT_CONFIG(regularexpression) + /*! \fn QByteArray QStringView::toLatin1() const diff --git a/src/corelib/text/qstringview.h b/src/corelib/text/qstringview.h index df05fce252..42935440f3 100644 --- a/src/corelib/text/qstringview.h +++ b/src/corelib/text/qstringview.h @@ -71,6 +71,7 @@ QT_BEGIN_NAMESPACE class QString; class QStringView; class QRegularExpression; +class QRegularExpressionMatch; namespace QtPrivate { template <typename Char> @@ -347,6 +348,25 @@ public: { return QtPrivate::lastIndexOf(*this, from, s, cs); } [[nodiscard]] inline qsizetype lastIndexOf(QLatin1String s, qsizetype from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept; +#if QT_CONFIG(regularexpression) + [[nodiscard]] qsizetype indexOf(const QRegularExpression &re, qsizetype from = 0, QRegularExpressionMatch *rmatch = nullptr) const + { + return QtPrivate::indexOf(*this, re, from, rmatch); + } + [[nodiscard]] qsizetype lastIndexOf(const QRegularExpression &re, qsizetype from = -1, QRegularExpressionMatch *rmatch = nullptr) const + { + return QtPrivate::lastIndexOf(*this, re, from, rmatch); + } + [[nodiscard]] bool contains(const QRegularExpression &re, QRegularExpressionMatch *rmatch = nullptr) const + { + return QtPrivate::contains(*this, re, rmatch); + } + [[nodiscard]] qsizetype count(const QRegularExpression &re) const + { + return QtPrivate::count(*this, re); + } +#endif + [[nodiscard]] bool isRightToLeft() const noexcept { return QtPrivate::isRightToLeft(*this); } [[nodiscard]] bool isValidUtf16() const noexcept |