1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2020 Giuseppe D'Angelo <dangelog@gmail.com>. |
4 | ** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> |
5 | ** Contact: https://www.qt.io/licensing/ |
6 | ** |
7 | ** This file is part of the QtCore module of the Qt Toolkit. |
8 | ** |
9 | ** $QT_BEGIN_LICENSE:LGPL$ |
10 | ** Commercial License Usage |
11 | ** Licensees holding valid commercial Qt licenses may use this file in |
12 | ** accordance with the commercial license agreement provided with the |
13 | ** Software or, alternatively, in accordance with the terms contained in |
14 | ** a written agreement between you and The Qt Company. For licensing terms |
15 | ** and conditions see https://www.qt.io/terms-conditions. For further |
16 | ** information use the contact form at https://www.qt.io/contact-us. |
17 | ** |
18 | ** GNU Lesser General Public License Usage |
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
20 | ** General Public License version 3 as published by the Free Software |
21 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
22 | ** packaging of this file. Please review the following information to |
23 | ** ensure the GNU Lesser General Public License version 3 requirements |
24 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
25 | ** |
26 | ** GNU General Public License Usage |
27 | ** Alternatively, this file may be used under the terms of the GNU |
28 | ** General Public License version 2.0 or (at your option) the GNU General |
29 | ** Public license version 3 or any later version approved by the KDE Free |
30 | ** Qt Foundation. The licenses are as published by the Free Software |
31 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
32 | ** included in the packaging of this file. Please review the following |
33 | ** information to ensure the GNU General Public License requirements will |
34 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
35 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
36 | ** |
37 | ** $QT_END_LICENSE$ |
38 | ** |
39 | ****************************************************************************/ |
40 | |
41 | #ifndef QREGULAREXPRESSION_H |
42 | #define QREGULAREXPRESSION_H |
43 | |
44 | #include <QtCore/qglobal.h> |
45 | #include <QtCore/qstring.h> |
46 | #include <QtCore/qstringview.h> |
47 | #include <QtCore/qshareddata.h> |
48 | #include <QtCore/qvariant.h> |
49 | |
50 | QT_REQUIRE_CONFIG(regularexpression); |
51 | |
52 | QT_BEGIN_NAMESPACE |
53 | |
54 | class QStringList; |
55 | class QLatin1String; |
56 | |
57 | class QRegularExpressionMatch; |
58 | class QRegularExpressionMatchIterator; |
59 | struct QRegularExpressionPrivate; |
60 | class QRegularExpression; |
61 | |
62 | Q_CORE_EXPORT uint qHash(const QRegularExpression &key, uint seed = 0) noexcept; |
63 | |
64 | class Q_CORE_EXPORT QRegularExpression |
65 | { |
66 | public: |
67 | enum PatternOption { |
68 | NoPatternOption = 0x0000, |
69 | CaseInsensitiveOption = 0x0001, |
70 | DotMatchesEverythingOption = 0x0002, |
71 | MultilineOption = 0x0004, |
72 | ExtendedPatternSyntaxOption = 0x0008, |
73 | InvertedGreedinessOption = 0x0010, |
74 | DontCaptureOption = 0x0020, |
75 | UseUnicodePropertiesOption = 0x0040, |
76 | OptimizeOnFirstUsageOption Q_DECL_ENUMERATOR_DEPRECATED_X("This option does not have any effect since Qt 5.12" ) = 0x0080, |
77 | DontAutomaticallyOptimizeOption Q_DECL_ENUMERATOR_DEPRECATED_X("This option does not have any effect since Qt 5.12" ) = 0x0100, |
78 | }; |
79 | Q_DECLARE_FLAGS(PatternOptions, PatternOption) |
80 | |
81 | PatternOptions patternOptions() const; |
82 | void setPatternOptions(PatternOptions options); |
83 | |
84 | QRegularExpression(); |
85 | explicit QRegularExpression(const QString &pattern, PatternOptions options = NoPatternOption); |
86 | QRegularExpression(const QRegularExpression &re); |
87 | ~QRegularExpression(); |
88 | QRegularExpression &operator=(const QRegularExpression &re); |
89 | QRegularExpression &operator=(QRegularExpression &&re) noexcept |
90 | { d.swap(other&: re.d); return *this; } |
91 | |
92 | void swap(QRegularExpression &other) noexcept { d.swap(other&: other.d); } |
93 | |
94 | QString pattern() const; |
95 | void setPattern(const QString &pattern); |
96 | |
97 | bool isValid() const; |
98 | int patternErrorOffset() const; |
99 | QString errorString() const; |
100 | |
101 | int captureCount() const; |
102 | QStringList namedCaptureGroups() const; |
103 | |
104 | enum MatchType { |
105 | NormalMatch = 0, |
106 | PartialPreferCompleteMatch, |
107 | PartialPreferFirstMatch, |
108 | NoMatch |
109 | }; |
110 | |
111 | enum MatchOption { |
112 | NoMatchOption = 0x0000, |
113 | AnchoredMatchOption = 0x0001, |
114 | DontCheckSubjectStringMatchOption = 0x0002 |
115 | }; |
116 | Q_DECLARE_FLAGS(MatchOptions, MatchOption) |
117 | |
118 | QRegularExpressionMatch match(const QString &subject, |
119 | int offset = 0, |
120 | MatchType matchType = NormalMatch, |
121 | MatchOptions matchOptions = NoMatchOption) const; |
122 | |
123 | QRegularExpressionMatch match(const QStringRef &subjectRef, |
124 | int offset = 0, |
125 | MatchType matchType = NormalMatch, |
126 | MatchOptions matchOptions = NoMatchOption) const; |
127 | |
128 | QRegularExpressionMatch match(QStringView subject, |
129 | int offset = 0, |
130 | MatchType matchType = NormalMatch, |
131 | MatchOptions matchOptions = NoMatchOption) const; |
132 | |
133 | QRegularExpressionMatchIterator globalMatch(const QString &subject, |
134 | int offset = 0, |
135 | MatchType matchType = NormalMatch, |
136 | MatchOptions matchOptions = NoMatchOption) const; |
137 | |
138 | QRegularExpressionMatchIterator globalMatch(const QStringRef &subjectRef, |
139 | int offset = 0, |
140 | MatchType matchType = NormalMatch, |
141 | MatchOptions matchOptions = NoMatchOption) const; |
142 | |
143 | QRegularExpressionMatchIterator globalMatch(QStringView subject, |
144 | int offset = 0, |
145 | MatchType matchType = NormalMatch, |
146 | MatchOptions matchOptions = NoMatchOption) const; |
147 | |
148 | void optimize() const; |
149 | |
150 | #if QT_STRINGVIEW_LEVEL < 2 |
151 | static QString escape(const QString &str); |
152 | static QString wildcardToRegularExpression(const QString &str); |
153 | static inline QString anchoredPattern(const QString &expression) |
154 | { |
155 | return anchoredPattern(expression: QStringView(expression)); |
156 | } |
157 | #endif |
158 | |
159 | static QString escape(QStringView str); |
160 | static QString wildcardToRegularExpression(QStringView str); |
161 | static QString anchoredPattern(QStringView expression); |
162 | |
163 | bool operator==(const QRegularExpression &re) const; |
164 | inline bool operator!=(const QRegularExpression &re) const { return !operator==(re); } |
165 | |
166 | private: |
167 | friend struct QRegularExpressionPrivate; |
168 | friend class QRegularExpressionMatch; |
169 | friend struct QRegularExpressionMatchPrivate; |
170 | friend class QRegularExpressionMatchIterator; |
171 | friend Q_CORE_EXPORT uint qHash(const QRegularExpression &key, uint seed) noexcept; |
172 | |
173 | QRegularExpression(QRegularExpressionPrivate &dd); |
174 | QExplicitlySharedDataPointer<QRegularExpressionPrivate> d; |
175 | }; |
176 | |
177 | Q_DECLARE_SHARED(QRegularExpression) |
178 | Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::PatternOptions) |
179 | Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::MatchOptions) |
180 | |
181 | #ifndef QT_NO_DATASTREAM |
182 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &out, const QRegularExpression &re); |
183 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &in, QRegularExpression &re); |
184 | #endif |
185 | |
186 | #ifndef QT_NO_DEBUG_STREAM |
187 | Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpression &re); |
188 | Q_CORE_EXPORT QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOptions); |
189 | #endif |
190 | |
191 | struct QRegularExpressionMatchPrivate; |
192 | |
193 | class Q_CORE_EXPORT QRegularExpressionMatch |
194 | { |
195 | public: |
196 | QRegularExpressionMatch(); |
197 | ~QRegularExpressionMatch(); |
198 | QRegularExpressionMatch(const QRegularExpressionMatch &match); |
199 | QRegularExpressionMatch &operator=(const QRegularExpressionMatch &match); |
200 | QRegularExpressionMatch &operator=(QRegularExpressionMatch &&match) noexcept |
201 | { d.swap(other&: match.d); return *this; } |
202 | void swap(QRegularExpressionMatch &other) noexcept { d.swap(other&: other.d); } |
203 | |
204 | QRegularExpression regularExpression() const; |
205 | QRegularExpression::MatchType matchType() const; |
206 | QRegularExpression::MatchOptions matchOptions() const; |
207 | |
208 | bool hasMatch() const; |
209 | bool hasPartialMatch() const; |
210 | |
211 | bool isValid() const; |
212 | |
213 | int lastCapturedIndex() const; |
214 | |
215 | QString captured(int nth = 0) const; |
216 | QStringRef capturedRef(int nth = 0) const; |
217 | QStringView capturedView(int nth = 0) const; |
218 | |
219 | #if QT_STRINGVIEW_LEVEL < 2 |
220 | QString captured(const QString &name) const; |
221 | QStringRef capturedRef(const QString &name) const; |
222 | #endif |
223 | |
224 | QString captured(QStringView name) const; |
225 | QStringRef capturedRef(QStringView name) const; |
226 | QStringView capturedView(QStringView name) const; |
227 | |
228 | QStringList capturedTexts() const; |
229 | |
230 | int capturedStart(int nth = 0) const; |
231 | int capturedLength(int nth = 0) const; |
232 | int capturedEnd(int nth = 0) const; |
233 | |
234 | #if QT_STRINGVIEW_LEVEL < 2 |
235 | int capturedStart(const QString &name) const; |
236 | int capturedLength(const QString &name) const; |
237 | int capturedEnd(const QString &name) const; |
238 | #endif |
239 | |
240 | int capturedStart(QStringView name) const; |
241 | int capturedLength(QStringView name) const; |
242 | int capturedEnd(QStringView name) const; |
243 | |
244 | private: |
245 | friend class QRegularExpression; |
246 | friend struct QRegularExpressionMatchPrivate; |
247 | friend class QRegularExpressionMatchIterator; |
248 | |
249 | QRegularExpressionMatch(QRegularExpressionMatchPrivate &dd); |
250 | QSharedDataPointer<QRegularExpressionMatchPrivate> d; |
251 | }; |
252 | |
253 | Q_DECLARE_SHARED(QRegularExpressionMatch) |
254 | |
255 | #ifndef QT_NO_DEBUG_STREAM |
256 | Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpressionMatch &match); |
257 | #endif |
258 | |
259 | struct QRegularExpressionMatchIteratorPrivate; |
260 | |
261 | class Q_CORE_EXPORT QRegularExpressionMatchIterator |
262 | { |
263 | public: |
264 | QRegularExpressionMatchIterator(); |
265 | ~QRegularExpressionMatchIterator(); |
266 | QRegularExpressionMatchIterator(const QRegularExpressionMatchIterator &iterator); |
267 | QRegularExpressionMatchIterator &operator=(const QRegularExpressionMatchIterator &iterator); |
268 | QRegularExpressionMatchIterator &operator=(QRegularExpressionMatchIterator &&iterator) noexcept |
269 | { d.swap(other&: iterator.d); return *this; } |
270 | void swap(QRegularExpressionMatchIterator &other) noexcept { d.swap(other&: other.d); } |
271 | |
272 | bool isValid() const; |
273 | |
274 | bool hasNext() const; |
275 | QRegularExpressionMatch next(); |
276 | QRegularExpressionMatch peekNext() const; |
277 | |
278 | QRegularExpression regularExpression() const; |
279 | QRegularExpression::MatchType matchType() const; |
280 | QRegularExpression::MatchOptions matchOptions() const; |
281 | |
282 | private: |
283 | friend class QRegularExpression; |
284 | |
285 | QRegularExpressionMatchIterator(QRegularExpressionMatchIteratorPrivate &dd); |
286 | QSharedDataPointer<QRegularExpressionMatchIteratorPrivate> d; |
287 | }; |
288 | |
289 | Q_DECLARE_SHARED(QRegularExpressionMatchIterator) |
290 | |
291 | inline |
292 | QRegularExpressionMatch QRegularExpression::match(QStringView subject, int offset, |
293 | QRegularExpression::MatchType matchType, MatchOptions matchOptions) const |
294 | { |
295 | return match(subject: subject.toString(), offset, matchType, matchOptions); |
296 | } |
297 | |
298 | inline |
299 | QRegularExpressionMatchIterator QRegularExpression::globalMatch(QStringView subject, int offset, |
300 | QRegularExpression::MatchType matchType, MatchOptions matchOptions) const |
301 | { |
302 | return globalMatch(subject: subject.toString(), offset, matchType, matchOptions); |
303 | } |
304 | |
305 | |
306 | // implementation here, so we have all required classes |
307 | inline |
308 | QList<QStringView> QStringView::split(const QRegularExpression &sep, Qt::SplitBehavior behavior) const |
309 | { |
310 | Q_ASSERT(int(m_size) == m_size); |
311 | QString s = QString::fromRawData(data(), size: int(m_size)); |
312 | const auto split = s.splitRef(sep, behavior); |
313 | QList<QStringView> result; |
314 | result.reserve(alloc: split.size()); |
315 | for (const QStringRef &r : split) |
316 | result.append(t: r); |
317 | return result; |
318 | } |
319 | |
320 | QT_END_NAMESPACE |
321 | |
322 | #endif // QREGULAREXPRESSION_H |
323 | |