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
50QT_REQUIRE_CONFIG(regularexpression);
51
52QT_BEGIN_NAMESPACE
53
54class QStringList;
55class QLatin1String;
56
57class QRegularExpressionMatch;
58class QRegularExpressionMatchIterator;
59struct QRegularExpressionPrivate;
60class QRegularExpression;
61
62Q_CORE_EXPORT uint qHash(const QRegularExpression &key, uint seed = 0) noexcept;
63
64class Q_CORE_EXPORT QRegularExpression
65{
66public:
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(re.d); return *this; }
91
92 void swap(QRegularExpression &other) noexcept { d.swap(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(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
166private:
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
177Q_DECLARE_SHARED(QRegularExpression)
178Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::PatternOptions)
179Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::MatchOptions)
180
181#ifndef QT_NO_DATASTREAM
182Q_CORE_EXPORT QDataStream &operator<<(QDataStream &out, const QRegularExpression &re);
183Q_CORE_EXPORT QDataStream &operator>>(QDataStream &in, QRegularExpression &re);
184#endif
185
186#ifndef QT_NO_DEBUG_STREAM
187Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpression &re);
188Q_CORE_EXPORT QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOptions);
189#endif
190
191struct QRegularExpressionMatchPrivate;
192
193class Q_CORE_EXPORT QRegularExpressionMatch
194{
195public:
196 QRegularExpressionMatch();
197 ~QRegularExpressionMatch();
198 QRegularExpressionMatch(const QRegularExpressionMatch &match);
199 QRegularExpressionMatch &operator=(const QRegularExpressionMatch &match);
200 QRegularExpressionMatch &operator=(QRegularExpressionMatch &&match) noexcept
201 { d.swap(match.d); return *this; }
202 void swap(QRegularExpressionMatch &other) noexcept { d.swap(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
244private:
245 friend class QRegularExpression;
246 friend struct QRegularExpressionMatchPrivate;
247 friend class QRegularExpressionMatchIterator;
248
249 QRegularExpressionMatch(QRegularExpressionMatchPrivate &dd);
250 QSharedDataPointer<QRegularExpressionMatchPrivate> d;
251};
252
253Q_DECLARE_SHARED(QRegularExpressionMatch)
254
255#ifndef QT_NO_DEBUG_STREAM
256Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpressionMatch &match);
257#endif
258
259struct QRegularExpressionMatchIteratorPrivate;
260
261class Q_CORE_EXPORT QRegularExpressionMatchIterator
262{
263public:
264 QRegularExpressionMatchIterator();
265 ~QRegularExpressionMatchIterator();
266 QRegularExpressionMatchIterator(const QRegularExpressionMatchIterator &iterator);
267 QRegularExpressionMatchIterator &operator=(const QRegularExpressionMatchIterator &iterator);
268 QRegularExpressionMatchIterator &operator=(QRegularExpressionMatchIterator &&iterator) noexcept
269 { d.swap(iterator.d); return *this; }
270 void swap(QRegularExpressionMatchIterator &other) noexcept { d.swap(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
282private:
283 friend class QRegularExpression;
284
285 QRegularExpressionMatchIterator(QRegularExpressionMatchIteratorPrivate &dd);
286 QSharedDataPointer<QRegularExpressionMatchIteratorPrivate> d;
287};
288
289Q_DECLARE_SHARED(QRegularExpressionMatchIterator)
290
291inline
292QRegularExpressionMatch QRegularExpression::match(QStringView subject, int offset,
293 QRegularExpression::MatchType matchType, MatchOptions matchOptions) const
294{
295 return match(subject.toString(), offset, matchType, matchOptions);
296}
297
298inline
299QRegularExpressionMatchIterator QRegularExpression::globalMatch(QStringView subject, int offset,
300 QRegularExpression::MatchType matchType, MatchOptions matchOptions) const
301{
302 return globalMatch(subject.toString(), offset, matchType, matchOptions);
303}
304
305
306// implementation here, so we have all required classes
307inline
308QList<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(), int(m_size));
312 const auto split = s.splitRef(sep, behavior);
313 QList<QStringView> result;
314 result.reserve(split.size());
315 for (const QStringRef &r : split)
316 result.append(r);
317 return result;
318}
319
320QT_END_NAMESPACE
321
322#endif // QREGULAREXPRESSION_H
323