1// Copyright (C) 2020 Giuseppe D'Angelo <dangelog@gmail.com>.
2// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
3// Copyright (C) 2021 The Qt Company Ltd.
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
6#ifndef QREGULAREXPRESSION_H
7#define QREGULAREXPRESSION_H
8
9#include <QtCore/qglobal.h>
10#include <QtCore/qstring.h>
11#include <QtCore/qstringview.h>
12#include <QtCore/qshareddata.h>
13#include <QtCore/qvariant.h>
14
15#include <iterator>
16
17QT_REQUIRE_CONFIG(regularexpression);
18
19QT_BEGIN_NAMESPACE
20
21class QRegularExpressionMatch;
22class QRegularExpressionMatchIterator;
23struct QRegularExpressionPrivate;
24class QRegularExpression;
25
26QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionPrivate, Q_CORE_EXPORT)
27
28Q_CORE_EXPORT size_t qHash(const QRegularExpression &key, size_t seed = 0) noexcept;
29
30class Q_CORE_EXPORT QRegularExpression
31{
32public:
33 enum PatternOption {
34 NoPatternOption = 0x0000,
35 CaseInsensitiveOption = 0x0001,
36 DotMatchesEverythingOption = 0x0002,
37 MultilineOption = 0x0004,
38 ExtendedPatternSyntaxOption = 0x0008,
39 InvertedGreedinessOption = 0x0010,
40 DontCaptureOption = 0x0020,
41 UseUnicodePropertiesOption = 0x0040,
42 // Formerly (no-ops deprecated in 5.12, removed 6.0):
43 // OptimizeOnFirstUsageOption = 0x0080,
44 // DontAutomaticallyOptimizeOption = 0x0100,
45 };
46 Q_DECLARE_FLAGS(PatternOptions, PatternOption)
47
48 PatternOptions patternOptions() const;
49 void setPatternOptions(PatternOptions options);
50
51 QRegularExpression();
52 explicit QRegularExpression(const QString &pattern, PatternOptions options = NoPatternOption);
53 QRegularExpression(const QRegularExpression &re) noexcept;
54 QRegularExpression(QRegularExpression &&re) = default;
55 ~QRegularExpression();
56 QRegularExpression &operator=(const QRegularExpression &re) noexcept;
57 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QRegularExpression)
58
59 void swap(QRegularExpression &other) noexcept { d.swap(other&: other.d); }
60
61 QString pattern() const;
62 void setPattern(const QString &pattern);
63
64 [[nodiscard]]
65 bool isValid() const;
66 qsizetype patternErrorOffset() const;
67 QString errorString() const;
68
69 int captureCount() const;
70 QStringList namedCaptureGroups() const;
71
72 enum MatchType {
73 NormalMatch = 0,
74 PartialPreferCompleteMatch,
75 PartialPreferFirstMatch,
76 NoMatch
77 };
78
79 enum MatchOption {
80 NoMatchOption = 0x0000,
81 AnchorAtOffsetMatchOption = 0x0001,
82 AnchoredMatchOption Q_DECL_ENUMERATOR_DEPRECATED_X(
83 "Use AnchorAtOffsetMatchOption instead") = AnchorAtOffsetMatchOption, // Rename@Qt6.0
84 DontCheckSubjectStringMatchOption = 0x0002
85 };
86 Q_DECLARE_FLAGS(MatchOptions, MatchOption)
87
88 [[nodiscard]]
89 QRegularExpressionMatch match(const QString &subject,
90 qsizetype offset = 0,
91 MatchType matchType = NormalMatch,
92 MatchOptions matchOptions = NoMatchOption) const;
93
94#if QT_DEPRECATED_SINCE(6, 8)
95 [[nodiscard]]
96 QT_DEPRECATED_VERSION_X_6_8("Use matchView instead.")
97 QRegularExpressionMatch match(QStringView subjectView,
98 qsizetype offset = 0,
99 MatchType matchType = NormalMatch,
100 MatchOptions matchOptions = NoMatchOption) const;
101#endif
102
103 [[nodiscard]]
104 QRegularExpressionMatch matchView(QStringView subjectView,
105 qsizetype offset = 0,
106 MatchType matchType = NormalMatch,
107 MatchOptions matchOptions = NoMatchOption) const;
108
109 [[nodiscard]]
110 QRegularExpressionMatchIterator globalMatch(const QString &subject,
111 qsizetype offset = 0,
112 MatchType matchType = NormalMatch,
113 MatchOptions matchOptions = NoMatchOption) const;
114
115#if QT_DEPRECATED_SINCE(6, 8)
116 [[nodiscard]]
117 QT_DEPRECATED_VERSION_X_6_8("Use globalMatchView instead.")
118 QRegularExpressionMatchIterator globalMatch(QStringView subjectView,
119 qsizetype offset = 0,
120 MatchType matchType = NormalMatch,
121 MatchOptions matchOptions = NoMatchOption) const;
122#endif
123
124 [[nodiscard]]
125 QRegularExpressionMatchIterator globalMatchView(QStringView subjectView,
126 qsizetype offset = 0,
127 MatchType matchType = NormalMatch,
128 MatchOptions matchOptions = NoMatchOption) const;
129
130 void optimize() const;
131
132 enum WildcardConversionOption {
133 DefaultWildcardConversion = 0x0,
134 UnanchoredWildcardConversion = 0x1,
135 NonPathWildcardConversion = 0x2,
136 };
137 Q_DECLARE_FLAGS(WildcardConversionOptions, WildcardConversionOption)
138
139 static QString escape(const QString &str)
140 {
141 return escape(str: qToStringViewIgnoringNull(s: str));
142 }
143
144 static QString wildcardToRegularExpression(const QString &str, WildcardConversionOptions options = DefaultWildcardConversion)
145 {
146 return wildcardToRegularExpression(str: qToStringViewIgnoringNull(s: str), options);
147 }
148
149 static inline QString anchoredPattern(const QString &expression)
150 {
151 return anchoredPattern(expression: qToStringViewIgnoringNull(s: expression));
152 }
153
154 static QString escape(QStringView str);
155 static QString wildcardToRegularExpression(QStringView str, WildcardConversionOptions options = DefaultWildcardConversion);
156 static QString anchoredPattern(QStringView expression);
157
158 static QRegularExpression fromWildcard(QStringView pattern, Qt::CaseSensitivity cs = Qt::CaseInsensitive,
159 WildcardConversionOptions options = DefaultWildcardConversion);
160#if QT_CORE_REMOVED_SINCE(6, 8)
161 bool operator==(const QRegularExpression &re) const;
162 inline bool operator!=(const QRegularExpression &re) const { return !operator==(re); }
163#endif
164private:
165 friend Q_CORE_EXPORT bool comparesEqual(const QRegularExpression &lhs,
166 const QRegularExpression &rhs) noexcept;
167 Q_DECLARE_EQUALITY_COMPARABLE(QRegularExpression)
168
169 friend struct QRegularExpressionPrivate;
170 friend class QRegularExpressionMatch;
171 friend struct QRegularExpressionMatchPrivate;
172 friend class QRegularExpressionMatchIterator;
173 friend Q_CORE_EXPORT size_t qHash(const QRegularExpression &key, size_t seed) noexcept;
174
175 QRegularExpression(QRegularExpressionPrivate &dd);
176 QExplicitlySharedDataPointer<QRegularExpressionPrivate> d;
177};
178
179Q_DECLARE_SHARED(QRegularExpression)
180Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::PatternOptions)
181Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::MatchOptions)
182Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::WildcardConversionOptions)
183
184#ifndef QT_NO_DATASTREAM
185Q_CORE_EXPORT QDataStream &operator<<(QDataStream &out, const QRegularExpression &re);
186Q_CORE_EXPORT QDataStream &operator>>(QDataStream &in, QRegularExpression &re);
187#endif
188
189#ifndef QT_NO_DEBUG_STREAM
190Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpression &re);
191Q_CORE_EXPORT QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOptions);
192#endif
193
194struct QRegularExpressionMatchPrivate;
195QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionMatchPrivate, Q_CORE_EXPORT)
196
197class Q_CORE_EXPORT QRegularExpressionMatch
198{
199public:
200 QRegularExpressionMatch();
201 ~QRegularExpressionMatch();
202 QRegularExpressionMatch(const QRegularExpressionMatch &match);
203 QRegularExpressionMatch(QRegularExpressionMatch &&match) = default;
204 QRegularExpressionMatch &operator=(const QRegularExpressionMatch &match);
205 QRegularExpressionMatch &operator=(QRegularExpressionMatch &&match) noexcept
206 { d.swap(other&: match.d); return *this; }
207 void swap(QRegularExpressionMatch &other) noexcept { d.swap(other&: other.d); }
208
209 QRegularExpression regularExpression() const;
210 QRegularExpression::MatchType matchType() const;
211 QRegularExpression::MatchOptions matchOptions() const;
212
213 bool hasMatch() const;
214 bool hasPartialMatch() const;
215
216 bool isValid() const;
217
218 int lastCapturedIndex() const;
219
220#if QT_CORE_REMOVED_SINCE(6, 8)
221 bool hasCaptured(const QString &name) const
222 { return hasCaptured(qToAnyStringViewIgnoringNull(name)); }
223 bool hasCaptured(QStringView name) const;
224#endif
225 bool hasCaptured(QAnyStringView name) const;
226 bool hasCaptured(int nth) const;
227
228 QString captured(int nth = 0) const;
229 QStringView capturedView(int nth = 0) const;
230
231#if QT_CORE_REMOVED_SINCE(6, 8)
232 QString captured(const QString &name) const
233 { return captured(qToAnyStringViewIgnoringNull(name)); }
234
235 QString captured(QStringView name) const;
236 QStringView capturedView(QStringView name) const;
237#endif
238 QString captured(QAnyStringView name) const;
239 QStringView capturedView(QAnyStringView name) const;
240
241 QStringList capturedTexts() const;
242
243 qsizetype capturedStart(int nth = 0) const;
244 qsizetype capturedLength(int nth = 0) const;
245 qsizetype capturedEnd(int nth = 0) const;
246
247#if QT_CORE_REMOVED_SINCE(6, 8)
248 qsizetype capturedStart(const QString &name) const
249 { return capturedStart(qToAnyStringViewIgnoringNull(name)); }
250 qsizetype capturedLength(const QString &name) const
251 { return capturedLength(qToAnyStringViewIgnoringNull(name)); }
252 qsizetype capturedEnd(const QString &name) const
253 { return capturedEnd(qToAnyStringViewIgnoringNull(name)); }
254
255 qsizetype capturedStart(QStringView name) const;
256 qsizetype capturedLength(QStringView name) const;
257 qsizetype capturedEnd(QStringView name) const;
258#endif
259 qsizetype capturedStart(QAnyStringView name) const;
260 qsizetype capturedLength(QAnyStringView name) const;
261 qsizetype capturedEnd(QAnyStringView name) const;
262
263private:
264 friend class QRegularExpression;
265 friend struct QRegularExpressionMatchPrivate;
266 friend class QRegularExpressionMatchIterator;
267
268 QRegularExpressionMatch(QRegularExpressionMatchPrivate &dd);
269 QExplicitlySharedDataPointer<QRegularExpressionMatchPrivate> d;
270};
271
272Q_DECLARE_SHARED(QRegularExpressionMatch)
273
274#ifndef QT_NO_DEBUG_STREAM
275Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpressionMatch &match);
276#endif
277
278namespace QtPrivate {
279class QRegularExpressionMatchIteratorRangeBasedForIterator;
280class QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel {};
281}
282
283struct QRegularExpressionMatchIteratorPrivate;
284QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionMatchIteratorPrivate, Q_CORE_EXPORT)
285
286class Q_CORE_EXPORT QRegularExpressionMatchIterator
287{
288public:
289 QRegularExpressionMatchIterator();
290 ~QRegularExpressionMatchIterator();
291 QRegularExpressionMatchIterator(const QRegularExpressionMatchIterator &iterator);
292 QRegularExpressionMatchIterator(QRegularExpressionMatchIterator &&iterator) = default;
293 QRegularExpressionMatchIterator &operator=(const QRegularExpressionMatchIterator &iterator);
294 QRegularExpressionMatchIterator &operator=(QRegularExpressionMatchIterator &&iterator) noexcept
295 { d.swap(other&: iterator.d); return *this; }
296 void swap(QRegularExpressionMatchIterator &other) noexcept { d.swap(other&: other.d); }
297
298 bool isValid() const;
299
300 bool hasNext() const;
301 QRegularExpressionMatch next();
302 QRegularExpressionMatch peekNext() const;
303
304 QRegularExpression regularExpression() const;
305 QRegularExpression::MatchType matchType() const;
306 QRegularExpression::MatchOptions matchOptions() const;
307
308private:
309 friend class QRegularExpression;
310 friend Q_CORE_EXPORT QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator);
311 friend QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel end(const QRegularExpressionMatchIterator &) { return {}; }
312
313 QRegularExpressionMatchIterator(QRegularExpressionMatchIteratorPrivate &dd);
314 QExplicitlySharedDataPointer<QRegularExpressionMatchIteratorPrivate> d;
315};
316
317namespace QtPrivate {
318
319// support for range-based for loop
320class QRegularExpressionMatchIteratorRangeBasedForIterator
321{
322public:
323 using value_type = QRegularExpressionMatch;
324 using difference_type = int;
325 using reference_type = const QRegularExpressionMatch &;
326 using pointer_type = const QRegularExpressionMatch *;
327 using iterator_category = std::forward_iterator_tag;
328
329 QRegularExpressionMatchIteratorRangeBasedForIterator()
330 : m_atEnd(true)
331 {
332 }
333
334 explicit QRegularExpressionMatchIteratorRangeBasedForIterator(const QRegularExpressionMatchIterator &iterator)
335 : m_matchIterator(iterator),
336 m_currentMatch(),
337 m_atEnd(false)
338 {
339 ++*this;
340 }
341
342 const QRegularExpressionMatch &operator*() const
343 {
344 Q_ASSERT_X(!m_atEnd, Q_FUNC_INFO, "operator* called on an iterator already at the end");
345 return m_currentMatch;
346 }
347
348 QRegularExpressionMatchIteratorRangeBasedForIterator &operator++()
349 {
350 Q_ASSERT_X(!m_atEnd, Q_FUNC_INFO, "operator++ called on an iterator already at the end");
351 if (m_matchIterator.hasNext()) {
352 m_currentMatch = m_matchIterator.next();
353 } else {
354 m_currentMatch = QRegularExpressionMatch();
355 m_atEnd = true;
356 }
357
358 return *this;
359 }
360
361 QRegularExpressionMatchIteratorRangeBasedForIterator operator++(int)
362 {
363 QRegularExpressionMatchIteratorRangeBasedForIterator i = *this;
364 ++*this;
365 return i;
366 }
367
368private:
369 // [input.iterators] imposes operator== on us. Unfortunately, it's not
370 // trivial to implement, so just do the bare minimum to satifisfy
371 // Cpp17EqualityComparable.
372 friend bool comparesEqual(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs,
373 const QRegularExpressionMatchIteratorRangeBasedForIterator &rhs)
374 noexcept
375 {
376 return (&lhs == &rhs);
377 }
378 Q_DECLARE_EQUALITY_COMPARABLE(QRegularExpressionMatchIteratorRangeBasedForIterator)
379
380 // This is what we really use in a range-based for.
381 friend bool comparesEqual(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs,
382 const QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel &rhs)
383 noexcept
384 {
385 Q_UNUSED(rhs);
386 return lhs.m_atEnd;
387 }
388 Q_DECLARE_EQUALITY_COMPARABLE(QRegularExpressionMatchIteratorRangeBasedForIterator,
389 QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel)
390
391 QRegularExpressionMatchIterator m_matchIterator;
392 QRegularExpressionMatch m_currentMatch;
393 bool m_atEnd;
394};
395
396} // namespace QtPrivate
397
398Q_DECLARE_SHARED(QRegularExpressionMatchIterator)
399
400QT_END_NAMESPACE
401
402#endif // QREGULAREXPRESSION_H
403

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/src/corelib/text/qregularexpression.h