Port QRegularExpression to QStringView, drop QStringRef
The idea is pretty simple -- add QRegularExpression matching over QStringView. When matching over a QString, keep the string alive (by taking a copy), and set the view onto that string. Otherwise, just use the view provided by the user (who is then responsible for ensuring the data stays valid while matching). Do just minor refactorings to support this use case in a cleaner fashion. In QRegularExpressionMatch drop the QStringRef-returning methods, as they cannot work any more -- in the general case there won't be a QString to build a QStringRef from. [ChangeLog][QtCore][QRegularExpression] All the APIs dealing with QStringRef have been ported to QStringView, following QStringRef deprecation in Qt 6.0. Change-Id: Ic367991d9583cc108c045e4387c9b7288c8f1ffd Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
32a39c4ed1
commit
529f052add
@ -162,7 +162,7 @@ void MainWindow::findCodecs()
|
|||||||
} else if (sortKey.startsWith(QLatin1String("UTF-16"))) {
|
} else if (sortKey.startsWith(QLatin1String("UTF-16"))) {
|
||||||
rank = 2;
|
rank = 2;
|
||||||
} else if ((match = iso8859RegExp.match(sortKey)).hasMatch()) {
|
} else if ((match = iso8859RegExp.match(sortKey)).hasMatch()) {
|
||||||
if (match.capturedRef(1).size() == 1)
|
if (match.capturedView(1).size() == 1)
|
||||||
rank = 3;
|
rank = 3;
|
||||||
else
|
else
|
||||||
rank = 4;
|
rank = 4;
|
||||||
|
@ -1210,7 +1210,7 @@ void QMessagePattern::setPattern(const QString &pattern)
|
|||||||
static const QRegularExpression separatorRx(QStringLiteral(" separator=(?|\"([^\"]*)\"|([^ }]*))"));
|
static const QRegularExpression separatorRx(QStringLiteral(" separator=(?|\"([^\"]*)\"|([^ }]*))"));
|
||||||
QRegularExpressionMatch m = depthRx.match(lexeme);
|
QRegularExpressionMatch m = depthRx.match(lexeme);
|
||||||
if (m.hasMatch()) {
|
if (m.hasMatch()) {
|
||||||
int depth = m.capturedRef(1).toInt();
|
int depth = m.capturedView(1).toInt();
|
||||||
if (depth <= 0)
|
if (depth <= 0)
|
||||||
error += QLatin1String("QT_MESSAGE_PATTERN: %{backtrace} depth must be a number greater than 0\n");
|
error += QLatin1String("QT_MESSAGE_PATTERN: %{backtrace} depth must be a number greater than 0\n");
|
||||||
else
|
else
|
||||||
|
@ -737,14 +737,10 @@ struct QRegularExpressionPrivate : QSharedData
|
|||||||
DontCheckSubjectString
|
DontCheckSubjectString
|
||||||
};
|
};
|
||||||
|
|
||||||
QRegularExpressionMatchPrivate *doMatch(const QString &subject,
|
void doMatch(QRegularExpressionMatchPrivate *priv,
|
||||||
int subjectStartPos,
|
int offset,
|
||||||
int subjectLength,
|
CheckSubjectStringOption checkSubjectStringOption = CheckSubjectString,
|
||||||
int offset,
|
const QRegularExpressionMatchPrivate *previous = nullptr) const;
|
||||||
QRegularExpression::MatchType matchType,
|
|
||||||
QRegularExpression::MatchOptions matchOptions,
|
|
||||||
CheckSubjectStringOption checkSubjectStringOption = CheckSubjectString,
|
|
||||||
const QRegularExpressionMatchPrivate *previous = nullptr) const;
|
|
||||||
|
|
||||||
int captureIndexForName(QStringView name) const;
|
int captureIndexForName(QStringView name) const;
|
||||||
|
|
||||||
@ -771,31 +767,33 @@ struct QRegularExpressionPrivate : QSharedData
|
|||||||
struct QRegularExpressionMatchPrivate : QSharedData
|
struct QRegularExpressionMatchPrivate : QSharedData
|
||||||
{
|
{
|
||||||
QRegularExpressionMatchPrivate(const QRegularExpression &re,
|
QRegularExpressionMatchPrivate(const QRegularExpression &re,
|
||||||
const QString &subject,
|
const QString &subjectStorage,
|
||||||
int subjectStart,
|
QStringView subject,
|
||||||
int subjectLength,
|
|
||||||
QRegularExpression::MatchType matchType,
|
QRegularExpression::MatchType matchType,
|
||||||
QRegularExpression::MatchOptions matchOptions);
|
QRegularExpression::MatchOptions matchOptions);
|
||||||
|
|
||||||
QRegularExpressionMatch nextMatch() const;
|
QRegularExpressionMatch nextMatch() const;
|
||||||
|
|
||||||
const QRegularExpression regularExpression;
|
const QRegularExpression regularExpression;
|
||||||
const QString subject;
|
|
||||||
// the capturedOffsets vector contains pairs of (start, end) positions
|
|
||||||
// for each captured substring
|
|
||||||
QVector<int> capturedOffsets;
|
|
||||||
|
|
||||||
const int subjectStart;
|
// subject is what we match upon. If we've been asked to match over
|
||||||
const int subjectLength;
|
// a QString, then subjectStorage is a copy of that string
|
||||||
|
// (so that it's kept alive by us)
|
||||||
|
const QString subjectStorage;
|
||||||
|
const QStringView subject;
|
||||||
|
|
||||||
const QRegularExpression::MatchType matchType;
|
const QRegularExpression::MatchType matchType;
|
||||||
const QRegularExpression::MatchOptions matchOptions;
|
const QRegularExpression::MatchOptions matchOptions;
|
||||||
|
|
||||||
int capturedCount;
|
// the capturedOffsets vector contains pairs of (start, end) positions
|
||||||
|
// for each captured substring
|
||||||
|
QVector<int> capturedOffsets;
|
||||||
|
|
||||||
bool hasMatch;
|
int capturedCount = 0;
|
||||||
bool hasPartialMatch;
|
|
||||||
bool isValid;
|
bool hasMatch = false;
|
||||||
|
bool hasPartialMatch = false;
|
||||||
|
bool isValid = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QRegularExpressionMatchIteratorPrivate : QSharedData
|
struct QRegularExpressionMatchIteratorPrivate : QSharedData
|
||||||
@ -1057,7 +1055,7 @@ int QRegularExpressionPrivate::captureIndexForName(QStringView name) const
|
|||||||
and re-run pcre2_match_16.
|
and re-run pcre2_match_16.
|
||||||
*/
|
*/
|
||||||
static int safe_pcre2_match_16(const pcre2_code_16 *code,
|
static int safe_pcre2_match_16(const pcre2_code_16 *code,
|
||||||
const unsigned short *subject, int length,
|
PCRE2_SPTR16 subject, int length,
|
||||||
int startOffset, int options,
|
int startOffset, int options,
|
||||||
pcre2_match_data_16 *matchData,
|
pcre2_match_data_16 *matchData,
|
||||||
pcre2_match_context_16 *matchContext)
|
pcre2_match_context_16 *matchContext)
|
||||||
@ -1079,20 +1077,19 @@ static int safe_pcre2_match_16(const pcre2_code_16 *code,
|
|||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
|
|
||||||
Performs a match on the substring of the given \a subject string,
|
Performs a match on the subject string view held by \a priv. The
|
||||||
substring which starts from \a subjectStart and up to
|
match will be of type priv->matchType and using the options
|
||||||
(but not including) \a subjectStart + \a subjectLength. The match
|
priv->matchOptions; the matching \a offset is relative the
|
||||||
will be of type \a matchType and using the options \a matchOptions;
|
substring, and if negative, it's taken as an offset from the end of
|
||||||
the matching \a offset is relative the substring,
|
the substring.
|
||||||
and if negative, it's taken as an offset from the end of the substring.
|
|
||||||
|
|
||||||
It also advances a match if a previous result is given as \a
|
It also advances a match if a previous result is given as \a
|
||||||
previous. The \a subject string goes a Unicode validity check if
|
previous. The subject string goes a Unicode validity check if
|
||||||
\a checkSubjectString is CheckSubjectString and the match options don't
|
\a checkSubjectString is CheckSubjectString and the match options don't
|
||||||
include DontCheckSubjectStringMatchOption (PCRE doesn't like illegal
|
include DontCheckSubjectStringMatchOption (PCRE doesn't like illegal
|
||||||
UTF-16 sequences).
|
UTF-16 sequences).
|
||||||
|
|
||||||
Returns the QRegularExpressionMatchPrivate of the result.
|
\a priv is modified to hold the results of the match.
|
||||||
|
|
||||||
Advancing a match is a tricky algorithm. If the previous match matched a
|
Advancing a match is a tricky algorithm. If the previous match matched a
|
||||||
non-empty string, we just do an ordinary match at the offset position.
|
non-empty string, we just do an ordinary match at the offset position.
|
||||||
@ -1105,43 +1102,38 @@ static int safe_pcre2_match_16(const pcre2_code_16 *code,
|
|||||||
the new advanced offset is pointing to the beginning of a CRLF sequence, we
|
the new advanced offset is pointing to the beginning of a CRLF sequence, we
|
||||||
must advance over it.
|
must advance over it.
|
||||||
*/
|
*/
|
||||||
QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString &subject,
|
void QRegularExpressionPrivate::doMatch(QRegularExpressionMatchPrivate *priv,
|
||||||
int subjectStart,
|
int offset,
|
||||||
int subjectLength,
|
CheckSubjectStringOption checkSubjectStringOption,
|
||||||
int offset,
|
const QRegularExpressionMatchPrivate *previous) const
|
||||||
QRegularExpression::MatchType matchType,
|
|
||||||
QRegularExpression::MatchOptions matchOptions,
|
|
||||||
CheckSubjectStringOption checkSubjectStringOption,
|
|
||||||
const QRegularExpressionMatchPrivate *previous) const
|
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(priv);
|
||||||
|
Q_ASSUME(priv != previous);
|
||||||
|
|
||||||
|
const int subjectLength = priv->subject.length();
|
||||||
|
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
offset += subjectLength;
|
offset += subjectLength;
|
||||||
|
|
||||||
QRegularExpression re(*const_cast<QRegularExpressionPrivate *>(this));
|
|
||||||
|
|
||||||
QRegularExpressionMatchPrivate *priv = new QRegularExpressionMatchPrivate(re, subject,
|
|
||||||
subjectStart, subjectLength,
|
|
||||||
matchType, matchOptions);
|
|
||||||
|
|
||||||
if (offset < 0 || offset > subjectLength)
|
if (offset < 0 || offset > subjectLength)
|
||||||
return priv;
|
return;
|
||||||
|
|
||||||
if (Q_UNLIKELY(!compiledPattern)) {
|
if (Q_UNLIKELY(!compiledPattern)) {
|
||||||
qWarning("QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object");
|
qWarning("QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object");
|
||||||
return priv;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip doing the actual matching if NoMatch type was requested
|
// skip doing the actual matching if NoMatch type was requested
|
||||||
if (matchType == QRegularExpression::NoMatch) {
|
if (priv->matchType == QRegularExpression::NoMatch) {
|
||||||
priv->isValid = true;
|
priv->isValid = true;
|
||||||
return priv;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcreOptions = convertToPcreOptions(matchOptions);
|
int pcreOptions = convertToPcreOptions(priv->matchOptions);
|
||||||
|
|
||||||
if (matchType == QRegularExpression::PartialPreferCompleteMatch)
|
if (priv->matchType == QRegularExpression::PartialPreferCompleteMatch)
|
||||||
pcreOptions |= PCRE2_PARTIAL_SOFT;
|
pcreOptions |= PCRE2_PARTIAL_SOFT;
|
||||||
else if (matchType == QRegularExpression::PartialPreferFirstMatch)
|
else if (priv->matchType == QRegularExpression::PartialPreferFirstMatch)
|
||||||
pcreOptions |= PCRE2_PARTIAL_HARD;
|
pcreOptions |= PCRE2_PARTIAL_HARD;
|
||||||
|
|
||||||
if (checkSubjectStringOption == DontCheckSubjectString)
|
if (checkSubjectStringOption == DontCheckSubjectString)
|
||||||
@ -1157,7 +1149,7 @@ QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString
|
|||||||
pcre2_jit_stack_assign_16(matchContext, &qtPcreCallback, nullptr);
|
pcre2_jit_stack_assign_16(matchContext, &qtPcreCallback, nullptr);
|
||||||
pcre2_match_data_16 *matchData = pcre2_match_data_create_from_pattern_16(compiledPattern, nullptr);
|
pcre2_match_data_16 *matchData = pcre2_match_data_create_from_pattern_16(compiledPattern, nullptr);
|
||||||
|
|
||||||
const unsigned short * const subjectUtf16 = subject.utf16() + subjectStart;
|
const char16_t * const subjectUtf16 = priv->subject.utf16();
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
@ -1194,9 +1186,8 @@ QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString
|
|||||||
|
|
||||||
#ifdef QREGULAREXPRESSION_DEBUG
|
#ifdef QREGULAREXPRESSION_DEBUG
|
||||||
qDebug() << "Matching" << pattern << "against" << subject
|
qDebug() << "Matching" << pattern << "against" << subject
|
||||||
<< "starting at" << subjectStart << "len" << subjectLength
|
|
||||||
<< "offset" << offset
|
<< "offset" << offset
|
||||||
<< matchType << matchOptions << previousMatchWasEmpty
|
<< priv->matchType << priv->matchOptions << previousMatchWasEmpty
|
||||||
<< "result" << result;
|
<< "result" << result;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1254,28 +1245,24 @@ QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString
|
|||||||
|
|
||||||
pcre2_match_data_free_16(matchData);
|
pcre2_match_data_free_16(matchData);
|
||||||
pcre2_match_context_free_16(matchContext);
|
pcre2_match_context_free_16(matchContext);
|
||||||
|
|
||||||
return priv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
QRegularExpressionMatchPrivate::QRegularExpressionMatchPrivate(const QRegularExpression &re,
|
QRegularExpressionMatchPrivate::QRegularExpressionMatchPrivate(const QRegularExpression &re,
|
||||||
const QString &subject,
|
const QString &subjectStorage,
|
||||||
int subjectStart,
|
QStringView subject,
|
||||||
int subjectLength,
|
|
||||||
QRegularExpression::MatchType matchType,
|
QRegularExpression::MatchType matchType,
|
||||||
QRegularExpression::MatchOptions matchOptions)
|
QRegularExpression::MatchOptions matchOptions)
|
||||||
: regularExpression(re), subject(subject),
|
: regularExpression(re),
|
||||||
subjectStart(subjectStart), subjectLength(subjectLength),
|
subjectStorage(subjectStorage),
|
||||||
matchType(matchType), matchOptions(matchOptions),
|
subject(subject),
|
||||||
capturedCount(0),
|
matchType(matchType),
|
||||||
hasMatch(false), hasPartialMatch(false), isValid(false)
|
matchOptions(matchOptions)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
@ -1284,18 +1271,20 @@ QRegularExpressionMatch QRegularExpressionMatchPrivate::nextMatch() const
|
|||||||
Q_ASSERT(isValid);
|
Q_ASSERT(isValid);
|
||||||
Q_ASSERT(hasMatch || hasPartialMatch);
|
Q_ASSERT(hasMatch || hasPartialMatch);
|
||||||
|
|
||||||
|
auto nextPrivate = new QRegularExpressionMatchPrivate(regularExpression,
|
||||||
|
subjectStorage,
|
||||||
|
subject,
|
||||||
|
matchType,
|
||||||
|
matchOptions);
|
||||||
|
|
||||||
// Note the DontCheckSubjectString passed for the check of the subject string:
|
// Note the DontCheckSubjectString passed for the check of the subject string:
|
||||||
// if we're advancing a match on the same subject,
|
// if we're advancing a match on the same subject,
|
||||||
// then that subject was already checked at least once (when this object
|
// then that subject was already checked at least once (when this object
|
||||||
// was created, or when the object that created this one was created, etc.)
|
// was created, or when the object that created this one was created, etc.)
|
||||||
QRegularExpressionMatchPrivate *nextPrivate = regularExpression.d->doMatch(subject,
|
regularExpression.d->doMatch(nextPrivate,
|
||||||
subjectStart,
|
capturedOffsets.at(1),
|
||||||
subjectLength,
|
QRegularExpressionPrivate::DontCheckSubjectString,
|
||||||
capturedOffsets.at(1),
|
this);
|
||||||
matchType,
|
|
||||||
matchOptions,
|
|
||||||
QRegularExpressionPrivate::DontCheckSubjectString,
|
|
||||||
this);
|
|
||||||
return QRegularExpressionMatch(*nextPrivate);
|
return QRegularExpressionMatch(*nextPrivate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1577,34 +1566,43 @@ QRegularExpressionMatch QRegularExpression::match(const QString &subject,
|
|||||||
MatchOptions matchOptions) const
|
MatchOptions matchOptions) const
|
||||||
{
|
{
|
||||||
d.data()->compilePattern();
|
d.data()->compilePattern();
|
||||||
|
auto priv = new QRegularExpressionMatchPrivate(*this,
|
||||||
QRegularExpressionMatchPrivate *priv = d->doMatch(subject, 0, subject.length(), offset, matchType, matchOptions);
|
subject,
|
||||||
|
qToStringViewIgnoringNull(subject),
|
||||||
|
matchType,
|
||||||
|
matchOptions);
|
||||||
|
d->doMatch(priv, offset);
|
||||||
return QRegularExpressionMatch(*priv);
|
return QRegularExpressionMatch(*priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\since 5.5
|
\since 6.0
|
||||||
\overload
|
\overload
|
||||||
|
|
||||||
Attempts to match the regular expression against the given \a subjectRef
|
Attempts to match the regular expression against the given \a subjectView
|
||||||
string reference, starting at the position \a offset inside the subject, using a
|
string view, starting at the position \a offset inside the subject, using a
|
||||||
match of type \a matchType and honoring the given \a matchOptions.
|
match of type \a matchType and honoring the given \a matchOptions.
|
||||||
|
|
||||||
The returned QRegularExpressionMatch object contains the results of the
|
The returned QRegularExpressionMatch object contains the results of the
|
||||||
match.
|
match.
|
||||||
|
|
||||||
|
\note The data referenced by \a subjectView must remain valid as long
|
||||||
|
as there are QRegularExpressionMatch objects using it.
|
||||||
|
|
||||||
\sa QRegularExpressionMatch, {normal matching}
|
\sa QRegularExpressionMatch, {normal matching}
|
||||||
*/
|
*/
|
||||||
QRegularExpressionMatch QRegularExpression::match(const QStringRef &subjectRef,
|
QRegularExpressionMatch QRegularExpression::match(QStringView subjectView,
|
||||||
int offset,
|
int offset,
|
||||||
MatchType matchType,
|
MatchType matchType,
|
||||||
MatchOptions matchOptions) const
|
MatchOptions matchOptions) const
|
||||||
{
|
{
|
||||||
d.data()->compilePattern();
|
d.data()->compilePattern();
|
||||||
|
auto priv = new QRegularExpressionMatchPrivate(*this,
|
||||||
const QString subject = subjectRef.string() ? *subjectRef.string() : QString();
|
QString(),
|
||||||
|
subjectView,
|
||||||
QRegularExpressionMatchPrivate *priv = d->doMatch(subject, subjectRef.position(), subjectRef.length(), offset, matchType, matchOptions);
|
matchType,
|
||||||
|
matchOptions);
|
||||||
|
d->doMatch(priv, offset);
|
||||||
return QRegularExpressionMatch(*priv);
|
return QRegularExpressionMatch(*priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1634,20 +1632,24 @@ QRegularExpressionMatchIterator QRegularExpression::globalMatch(const QString &s
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\since 5.5
|
\since 6.0
|
||||||
\overload
|
\overload
|
||||||
|
|
||||||
Attempts to perform a global match of the regular expression against the
|
Attempts to perform a global match of the regular expression against the
|
||||||
given \a subjectRef string reference, starting at the position \a offset inside the
|
given \a subjectView string view, starting at the position \a offset inside the
|
||||||
subject, using a match of type \a matchType and honoring the given \a
|
subject, using a match of type \a matchType and honoring the given \a
|
||||||
matchOptions.
|
matchOptions.
|
||||||
|
|
||||||
The returned QRegularExpressionMatchIterator is positioned before the
|
The returned QRegularExpressionMatchIterator is positioned before the
|
||||||
first match result (if any).
|
first match result (if any).
|
||||||
|
|
||||||
|
\note The data referenced by \a subjectView must remain valid as
|
||||||
|
long as there are QRegularExpressionMatchIterator or
|
||||||
|
QRegularExpressionMatch objects using it.
|
||||||
|
|
||||||
\sa QRegularExpressionMatchIterator, {global matching}
|
\sa QRegularExpressionMatchIterator, {global matching}
|
||||||
*/
|
*/
|
||||||
QRegularExpressionMatchIterator QRegularExpression::globalMatch(const QStringRef &subjectRef,
|
QRegularExpressionMatchIterator QRegularExpression::globalMatch(QStringView subjectView,
|
||||||
int offset,
|
int offset,
|
||||||
MatchType matchType,
|
MatchType matchType,
|
||||||
MatchOptions matchOptions) const
|
MatchOptions matchOptions) const
|
||||||
@ -1656,7 +1658,7 @@ QRegularExpressionMatchIterator QRegularExpression::globalMatch(const QStringRef
|
|||||||
new QRegularExpressionMatchIteratorPrivate(*this,
|
new QRegularExpressionMatchIteratorPrivate(*this,
|
||||||
matchType,
|
matchType,
|
||||||
matchOptions,
|
matchOptions,
|
||||||
match(subjectRef, offset, matchType, matchOptions));
|
match(subjectView, offset, matchType, matchOptions));
|
||||||
|
|
||||||
return QRegularExpressionMatchIterator(*priv);
|
return QRegularExpressionMatchIterator(*priv);
|
||||||
}
|
}
|
||||||
@ -1987,8 +1989,7 @@ QString QRegularExpression::anchoredPattern(QStringView expression)
|
|||||||
QRegularExpressionMatch::QRegularExpressionMatch()
|
QRegularExpressionMatch::QRegularExpressionMatch()
|
||||||
: d(new QRegularExpressionMatchPrivate(QRegularExpression(),
|
: d(new QRegularExpressionMatchPrivate(QRegularExpression(),
|
||||||
QString(),
|
QString(),
|
||||||
0,
|
QStringView(),
|
||||||
0,
|
|
||||||
QRegularExpression::NoMatch,
|
QRegularExpression::NoMatch,
|
||||||
QRegularExpression::NoMatchOption))
|
QRegularExpression::NoMatchOption))
|
||||||
{
|
{
|
||||||
@ -2108,45 +2109,12 @@ int QRegularExpressionMatch::lastCapturedIndex() const
|
|||||||
\note The implicit capturing group number 0 captures the substring matched
|
\note The implicit capturing group number 0 captures the substring matched
|
||||||
by the entire pattern.
|
by the entire pattern.
|
||||||
|
|
||||||
\sa capturedRef(), capturedView(), lastCapturedIndex(), capturedStart(), capturedEnd(),
|
\sa capturedView(), lastCapturedIndex(), capturedStart(), capturedEnd(),
|
||||||
capturedLength(), QString::isNull()
|
capturedLength(), QString::isNull()
|
||||||
*/
|
*/
|
||||||
QString QRegularExpressionMatch::captured(int nth) const
|
QString QRegularExpressionMatch::captured(int nth) const
|
||||||
{
|
{
|
||||||
if (nth < 0 || nth > lastCapturedIndex())
|
return capturedView(nth).toString();
|
||||||
return QString();
|
|
||||||
|
|
||||||
int start = capturedStart(nth);
|
|
||||||
|
|
||||||
if (start == -1) // didn't capture
|
|
||||||
return QString();
|
|
||||||
|
|
||||||
return d->subject.mid(start + d->subjectStart, capturedLength(nth));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns a reference to the substring captured by the \a nth capturing group.
|
|
||||||
|
|
||||||
If the \a nth capturing group did not capture a string, or if there is no
|
|
||||||
such capturing group, returns a null QStringRef.
|
|
||||||
|
|
||||||
\note The implicit capturing group number 0 captures the substring matched
|
|
||||||
by the entire pattern.
|
|
||||||
|
|
||||||
\sa captured(), capturedView(), lastCapturedIndex(), capturedStart(), capturedEnd(),
|
|
||||||
capturedLength(), QStringRef::isNull()
|
|
||||||
*/
|
|
||||||
QStringRef QRegularExpressionMatch::capturedRef(int nth) const
|
|
||||||
{
|
|
||||||
if (nth < 0 || nth > lastCapturedIndex())
|
|
||||||
return QStringRef();
|
|
||||||
|
|
||||||
int start = capturedStart(nth);
|
|
||||||
|
|
||||||
if (start == -1) // didn't capture
|
|
||||||
return QStringRef();
|
|
||||||
|
|
||||||
return d->subject.midRef(start + d->subjectStart, capturedLength(nth));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2160,12 +2128,20 @@ QStringRef QRegularExpressionMatch::capturedRef(int nth) const
|
|||||||
\note The implicit capturing group number 0 captures the substring matched
|
\note The implicit capturing group number 0 captures the substring matched
|
||||||
by the entire pattern.
|
by the entire pattern.
|
||||||
|
|
||||||
\sa captured(), capturedRef(), lastCapturedIndex(), capturedStart(), capturedEnd(),
|
\sa captured(), lastCapturedIndex(), capturedStart(), capturedEnd(),
|
||||||
capturedLength(), QStringView::isNull()
|
capturedLength(), QStringView::isNull()
|
||||||
*/
|
*/
|
||||||
QStringView QRegularExpressionMatch::capturedView(int nth) const
|
QStringView QRegularExpressionMatch::capturedView(int nth) const
|
||||||
{
|
{
|
||||||
return capturedRef(nth);
|
if (nth < 0 || nth > lastCapturedIndex())
|
||||||
|
return QStringView();
|
||||||
|
|
||||||
|
int start = capturedStart(nth);
|
||||||
|
|
||||||
|
if (start == -1) // didn't capture
|
||||||
|
return QStringView();
|
||||||
|
|
||||||
|
return d->subject.mid(start, capturedLength(nth));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_STRINGVIEW_LEVEL < 2
|
#if QT_STRINGVIEW_LEVEL < 2
|
||||||
@ -2175,28 +2151,13 @@ QStringView QRegularExpressionMatch::capturedView(int nth) const
|
|||||||
If the named capturing group \a name did not capture a string, or if
|
If the named capturing group \a name did not capture a string, or if
|
||||||
there is no capturing group named \a name, returns a null QString.
|
there is no capturing group named \a name, returns a null QString.
|
||||||
|
|
||||||
\sa capturedRef(), capturedView(), capturedStart(), capturedEnd(), capturedLength(),
|
\sa capturedView(), capturedStart(), capturedEnd(), capturedLength(),
|
||||||
QString::isNull()
|
QString::isNull()
|
||||||
*/
|
*/
|
||||||
QString QRegularExpressionMatch::captured(const QString &name) const
|
QString QRegularExpressionMatch::captured(const QString &name) const
|
||||||
{
|
{
|
||||||
return captured(qToStringViewIgnoringNull(name));
|
return captured(qToStringViewIgnoringNull(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns a reference to the string captured by the capturing group named \a
|
|
||||||
name.
|
|
||||||
|
|
||||||
If the named capturing group \a name did not capture a string, or if
|
|
||||||
there is no capturing group named \a name, returns a null QStringRef.
|
|
||||||
|
|
||||||
\sa captured(), capturedView(), capturedStart(), capturedEnd(), capturedLength(),
|
|
||||||
QStringRef::isNull()
|
|
||||||
*/
|
|
||||||
QStringRef QRegularExpressionMatch::capturedRef(const QString &name) const
|
|
||||||
{
|
|
||||||
return capturedRef(qToStringViewIgnoringNull(name));
|
|
||||||
}
|
|
||||||
#endif // QT_STRINGVIEW_LEVEL < 2
|
#endif // QT_STRINGVIEW_LEVEL < 2
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2207,7 +2168,7 @@ QStringRef QRegularExpressionMatch::capturedRef(const QString &name) const
|
|||||||
If the named capturing group \a name did not capture a string, or if
|
If the named capturing group \a name did not capture a string, or if
|
||||||
there is no capturing group named \a name, returns a null QString.
|
there is no capturing group named \a name, returns a null QString.
|
||||||
|
|
||||||
\sa capturedRef(), capturedView(), capturedStart(), capturedEnd(), capturedLength(),
|
\sa capturedView(), capturedStart(), capturedEnd(), capturedLength(),
|
||||||
QString::isNull()
|
QString::isNull()
|
||||||
*/
|
*/
|
||||||
QString QRegularExpressionMatch::captured(QStringView name) const
|
QString QRegularExpressionMatch::captured(QStringView name) const
|
||||||
@ -2216,34 +2177,8 @@ QString QRegularExpressionMatch::captured(QStringView name) const
|
|||||||
qWarning("QRegularExpressionMatch::captured: empty capturing group name passed");
|
qWarning("QRegularExpressionMatch::captured: empty capturing group name passed");
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
int nth = d->regularExpression.d->captureIndexForName(name);
|
|
||||||
if (nth == -1)
|
|
||||||
return QString();
|
|
||||||
return captured(nth);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
return capturedView(name).toString();
|
||||||
\since 5.10
|
|
||||||
|
|
||||||
Returns a reference to the string captured by the capturing group named \a
|
|
||||||
name.
|
|
||||||
|
|
||||||
If the named capturing group \a name did not capture a string, or if
|
|
||||||
there is no capturing group named \a name, returns a null QStringRef.
|
|
||||||
|
|
||||||
\sa captured(), capturedView(), capturedStart(), capturedEnd(), capturedLength(),
|
|
||||||
QStringRef::isNull()
|
|
||||||
*/
|
|
||||||
QStringRef QRegularExpressionMatch::capturedRef(QStringView name) const
|
|
||||||
{
|
|
||||||
if (name.isEmpty()) {
|
|
||||||
qWarning("QRegularExpressionMatch::capturedRef: empty capturing group name passed");
|
|
||||||
return QStringRef();
|
|
||||||
}
|
|
||||||
int nth = d->regularExpression.d->captureIndexForName(name);
|
|
||||||
if (nth == -1)
|
|
||||||
return QStringRef();
|
|
||||||
return capturedRef(nth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2255,7 +2190,7 @@ QStringRef QRegularExpressionMatch::capturedRef(QStringView name) const
|
|||||||
If the named capturing group \a name did not capture a string, or if
|
If the named capturing group \a name did not capture a string, or if
|
||||||
there is no capturing group named \a name, returns a null QStringView.
|
there is no capturing group named \a name, returns a null QStringView.
|
||||||
|
|
||||||
\sa captured(), capturedRef(), capturedStart(), capturedEnd(), capturedLength(),
|
\sa captured(), capturedStart(), capturedEnd(), capturedLength(),
|
||||||
QStringRef::isNull()
|
QStringRef::isNull()
|
||||||
*/
|
*/
|
||||||
QStringView QRegularExpressionMatch::capturedView(QStringView name) const
|
QStringView QRegularExpressionMatch::capturedView(QStringView name) const
|
||||||
|
@ -121,7 +121,7 @@ public:
|
|||||||
MatchType matchType = NormalMatch,
|
MatchType matchType = NormalMatch,
|
||||||
MatchOptions matchOptions = NoMatchOption) const;
|
MatchOptions matchOptions = NoMatchOption) const;
|
||||||
|
|
||||||
QRegularExpressionMatch match(const QStringRef &subjectRef,
|
QRegularExpressionMatch match(QStringView subjectView,
|
||||||
int offset = 0,
|
int offset = 0,
|
||||||
MatchType matchType = NormalMatch,
|
MatchType matchType = NormalMatch,
|
||||||
MatchOptions matchOptions = NoMatchOption) const;
|
MatchOptions matchOptions = NoMatchOption) const;
|
||||||
@ -131,7 +131,7 @@ public:
|
|||||||
MatchType matchType = NormalMatch,
|
MatchType matchType = NormalMatch,
|
||||||
MatchOptions matchOptions = NoMatchOption) const;
|
MatchOptions matchOptions = NoMatchOption) const;
|
||||||
|
|
||||||
QRegularExpressionMatchIterator globalMatch(const QStringRef &subjectRef,
|
QRegularExpressionMatchIterator globalMatch(QStringView subjectView,
|
||||||
int offset = 0,
|
int offset = 0,
|
||||||
MatchType matchType = NormalMatch,
|
MatchType matchType = NormalMatch,
|
||||||
MatchOptions matchOptions = NoMatchOption) const;
|
MatchOptions matchOptions = NoMatchOption) const;
|
||||||
@ -221,16 +221,13 @@ public:
|
|||||||
int lastCapturedIndex() const;
|
int lastCapturedIndex() const;
|
||||||
|
|
||||||
QString captured(int nth = 0) const;
|
QString captured(int nth = 0) const;
|
||||||
QStringRef capturedRef(int nth = 0) const;
|
|
||||||
QStringView capturedView(int nth = 0) const;
|
QStringView capturedView(int nth = 0) const;
|
||||||
|
|
||||||
#if QT_STRINGVIEW_LEVEL < 2
|
#if QT_STRINGVIEW_LEVEL < 2
|
||||||
QString captured(const QString &name) const;
|
QString captured(const QString &name) const;
|
||||||
QStringRef capturedRef(const QString &name) const;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QString captured(QStringView name) const;
|
QString captured(QStringView name) const;
|
||||||
QStringRef capturedRef(QStringView name) const;
|
|
||||||
QStringView capturedView(QStringView name) const;
|
QStringView capturedView(QStringView name) const;
|
||||||
|
|
||||||
QStringList capturedTexts() const;
|
QStringList capturedTexts() const;
|
||||||
|
@ -1066,14 +1066,14 @@ static QPSQLDriver::Protocol qFindPSQLVersion(const QString &versionString)
|
|||||||
// increasing the first part of the version, e.g. 10 to 11.
|
// increasing the first part of the version, e.g. 10 to 11.
|
||||||
// Before version 10, a major release was indicated by increasing either
|
// Before version 10, a major release was indicated by increasing either
|
||||||
// the first or second part of the version number, e.g. 9.5 to 9.6.
|
// the first or second part of the version number, e.g. 9.5 to 9.6.
|
||||||
int vMaj = match.capturedRef(1).toInt();
|
int vMaj = match.capturedView(1).toInt();
|
||||||
int vMin;
|
int vMin;
|
||||||
if (vMaj >= 10) {
|
if (vMaj >= 10) {
|
||||||
vMin = 0;
|
vMin = 0;
|
||||||
} else {
|
} else {
|
||||||
if (match.capturedRef(2).isEmpty())
|
if (match.capturedView(2).isEmpty())
|
||||||
return QPSQLDriver::VersionUnknown;
|
return QPSQLDriver::VersionUnknown;
|
||||||
vMin = match.capturedRef(2).toInt();
|
vMin = match.capturedView(2).toInt();
|
||||||
}
|
}
|
||||||
return qMakePSQLVersion(vMaj, vMin);
|
return qMakePSQLVersion(vMaj, vMin);
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,6 @@ void consistencyCheck(const QRegularExpressionMatch &match)
|
|||||||
int endPos = match.capturedEnd(i);
|
int endPos = match.capturedEnd(i);
|
||||||
int length = match.capturedLength(i);
|
int length = match.capturedLength(i);
|
||||||
QString captured = match.captured(i);
|
QString captured = match.captured(i);
|
||||||
QStringRef capturedRef = match.capturedRef(i);
|
|
||||||
QStringView capturedView = match.capturedView(i);
|
QStringView capturedView = match.capturedView(i);
|
||||||
|
|
||||||
if (!captured.isNull()) {
|
if (!captured.isNull()) {
|
||||||
@ -226,13 +225,11 @@ void consistencyCheck(const QRegularExpressionMatch &match)
|
|||||||
QVERIFY(length >= 0);
|
QVERIFY(length >= 0);
|
||||||
QVERIFY(endPos >= startPos);
|
QVERIFY(endPos >= startPos);
|
||||||
QVERIFY((endPos - startPos) == length);
|
QVERIFY((endPos - startPos) == length);
|
||||||
QVERIFY(captured == capturedRef);
|
|
||||||
QVERIFY(captured == capturedView);
|
QVERIFY(captured == capturedView);
|
||||||
} else {
|
} else {
|
||||||
QVERIFY(startPos == -1);
|
QVERIFY(startPos == -1);
|
||||||
QVERIFY(endPos == -1);
|
QVERIFY(endPos == -1);
|
||||||
QVERIFY((endPos - startPos) == length);
|
QVERIFY((endPos - startPos) == length);
|
||||||
QVERIFY(capturedRef.isNull());
|
|
||||||
QVERIFY(capturedView.isNull());
|
QVERIFY(capturedView.isNull());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,10 +341,10 @@ static void testMatch(const QRegularExpression ®exp,
|
|||||||
// test with QString as subject type
|
// test with QString as subject type
|
||||||
testMatchImpl<QREMatch>(regexp, matchingMethodForString, subject, offset, matchType, matchOptions, result);
|
testMatchImpl<QREMatch>(regexp, matchingMethodForString, subject, offset, matchType, matchOptions, result);
|
||||||
|
|
||||||
// test with QStringRef as subject type
|
// test with QStringView as subject type
|
||||||
testMatchImpl<QREMatch>(regexp,
|
testMatchImpl<QREMatch>(regexp,
|
||||||
matchingMethodForStringRef,
|
matchingMethodForStringRef,
|
||||||
QStringRef(&subject, 0, subject.length()),
|
QStringView(subject),
|
||||||
offset,
|
offset,
|
||||||
matchType,
|
matchType,
|
||||||
matchOptions,
|
matchOptions,
|
||||||
@ -355,9 +352,9 @@ static void testMatch(const QRegularExpression ®exp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringPMF)(const QString &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
|
typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringPMF)(const QString &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
|
||||||
typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringRefPMF)(const QStringRef &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
|
typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringViewPMF)(QStringView, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
|
||||||
typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringPMF)(const QString &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
|
typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringPMF)(const QString &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
|
||||||
typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringRefPMF)(const QStringRef &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
|
typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringViewPMF)(QStringView, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
|
||||||
|
|
||||||
void tst_QRegularExpression::provideRegularExpressions()
|
void tst_QRegularExpression::provideRegularExpressions()
|
||||||
{
|
{
|
||||||
@ -866,7 +863,7 @@ void tst_QRegularExpression::normalMatch()
|
|||||||
|
|
||||||
testMatch<QRegularExpressionMatch>(regexp,
|
testMatch<QRegularExpressionMatch>(regexp,
|
||||||
static_cast<QREMatchStringPMF>(&QRegularExpression::match),
|
static_cast<QREMatchStringPMF>(&QRegularExpression::match),
|
||||||
static_cast<QREMatchStringRefPMF>(&QRegularExpression::match),
|
static_cast<QREMatchStringViewPMF>(&QRegularExpression::match),
|
||||||
subject,
|
subject,
|
||||||
offset,
|
offset,
|
||||||
QRegularExpression::NormalMatch,
|
QRegularExpression::NormalMatch,
|
||||||
@ -1138,7 +1135,7 @@ void tst_QRegularExpression::partialMatch()
|
|||||||
|
|
||||||
testMatch<QRegularExpressionMatch>(regexp,
|
testMatch<QRegularExpressionMatch>(regexp,
|
||||||
static_cast<QREMatchStringPMF>(&QRegularExpression::match),
|
static_cast<QREMatchStringPMF>(&QRegularExpression::match),
|
||||||
static_cast<QREMatchStringRefPMF>(&QRegularExpression::match),
|
static_cast<QREMatchStringViewPMF>(&QRegularExpression::match),
|
||||||
subject,
|
subject,
|
||||||
offset,
|
offset,
|
||||||
matchType,
|
matchType,
|
||||||
@ -1415,7 +1412,7 @@ void tst_QRegularExpression::globalMatch()
|
|||||||
|
|
||||||
testMatch<QRegularExpressionMatchIterator>(regexp,
|
testMatch<QRegularExpressionMatchIterator>(regexp,
|
||||||
static_cast<QREGlobalMatchStringPMF>(&QRegularExpression::globalMatch),
|
static_cast<QREGlobalMatchStringPMF>(&QRegularExpression::globalMatch),
|
||||||
static_cast<QREGlobalMatchStringRefPMF>(&QRegularExpression::globalMatch),
|
static_cast<QREGlobalMatchStringViewPMF>(&QRegularExpression::globalMatch),
|
||||||
subject,
|
subject,
|
||||||
offset,
|
offset,
|
||||||
matchType,
|
matchType,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user