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** Copyright (C) 2016 The Qt Company Ltd.
6** Contact: https://www.qt.io/licensing/
7**
8** This file is part of the QtCore module of the Qt Toolkit.
9**
10** $QT_BEGIN_LICENSE:LGPL$
11** Commercial License Usage
12** Licensees holding valid commercial Qt licenses may use this file in
13** accordance with the commercial license agreement provided with the
14** Software or, alternatively, in accordance with the terms contained in
15** a written agreement between you and The Qt Company. For licensing terms
16** and conditions see https://www.qt.io/terms-conditions. For further
17** information use the contact form at https://www.qt.io/contact-us.
18**
19** GNU Lesser General Public License Usage
20** Alternatively, this file may be used under the terms of the GNU Lesser
21** General Public License version 3 as published by the Free Software
22** Foundation and appearing in the file LICENSE.LGPL3 included in the
23** packaging of this file. Please review the following information to
24** ensure the GNU Lesser General Public License version 3 requirements
25** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26**
27** GNU General Public License Usage
28** Alternatively, this file may be used under the terms of the GNU
29** General Public License version 2.0 or (at your option) the GNU General
30** Public license version 3 or any later version approved by the KDE Free
31** Qt Foundation. The licenses are as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33** included in the packaging of this file. Please review the following
34** information to ensure the GNU General Public License requirements will
35** be met: https://www.gnu.org/licenses/gpl-2.0.html and
36** https://www.gnu.org/licenses/gpl-3.0.html.
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qregularexpression.h"
43
44#include <QtCore/qcoreapplication.h>
45#include <QtCore/qhashfunctions.h>
46#include <QtCore/qmutex.h>
47#include <QtCore/qvector.h>
48#include <QtCore/qstringlist.h>
49#include <QtCore/qdebug.h>
50#include <QtCore/qthreadstorage.h>
51#include <QtCore/qglobal.h>
52#include <QtCore/qatomic.h>
53#include <QtCore/qdatastream.h>
54
55#if defined(Q_OS_MACOS)
56#include <QtCore/private/qcore_mac_p.h>
57#endif
58
59#define PCRE2_CODE_UNIT_WIDTH 16
60
61#include <pcre2.h>
62
63QT_BEGIN_NAMESPACE
64
65/*!
66 \class QRegularExpression
67 \inmodule QtCore
68 \reentrant
69
70 \brief The QRegularExpression class provides pattern matching using regular
71 expressions.
72
73 \since 5.0
74
75 \ingroup tools
76 \ingroup shared
77
78 \keyword regular expression
79
80 Regular expressions, or \e{regexps}, are a very powerful tool to handle
81 strings and texts. This is useful in many contexts, e.g.,
82
83 \table
84 \row \li Validation
85 \li A regexp can test whether a substring meets some criteria,
86 e.g. is an integer or contains no whitespace.
87 \row \li Searching
88 \li A regexp provides more powerful pattern matching than
89 simple substring matching, e.g., match one of the words
90 \e{mail}, \e{letter} or \e{correspondence}, but none of the
91 words \e{email}, \e{mailman}, \e{mailer}, \e{letterbox}, etc.
92 \row \li Search and Replace
93 \li A regexp can replace all occurrences of a substring with a
94 different substring, e.g., replace all occurrences of \e{&}
95 with \e{\&amp;} except where the \e{&} is already followed by
96 an \e{amp;}.
97 \row \li String Splitting
98 \li A regexp can be used to identify where a string should be
99 split apart, e.g. splitting tab-delimited strings.
100 \endtable
101
102 This document is by no means a complete reference to pattern matching using
103 regular expressions, and the following parts will require the reader to
104 have some basic knowledge about Perl-like regular expressions and their
105 pattern syntax.
106
107 Good references about regular expressions include:
108
109 \list
110 \li \e {Mastering Regular Expressions} (Third Edition) by Jeffrey E. F.
111 Friedl, ISBN 0-596-52812-4;
112 \li the \l{http://pcre.org/pcre.txt} {pcrepattern(3)} man page, describing
113 the pattern syntax supported by PCRE (the reference implementation of
114 Perl-compatible regular expressions);
115 \li the \l{http://perldoc.perl.org/perlre.html} {Perl's regular expression
116 documentation} and the \l{http://perldoc.perl.org/perlretut.html} {Perl's
117 regular expression tutorial}.
118 \endlist
119
120 \tableofcontents
121
122 \section1 Introduction
123
124 QRegularExpression implements Perl-compatible regular expressions. It fully
125 supports Unicode. For an overview of the regular expression syntax
126 supported by QRegularExpression, please refer to the aforementioned
127 pcrepattern(3) man page. A regular expression is made up of two things: a
128 \b{pattern string} and a set of \b{pattern options} that change the
129 meaning of the pattern string.
130
131 You can set the pattern string by passing a string to the QRegularExpression
132 constructor:
133
134 \snippet code/src_corelib_tools_qregularexpression.cpp 0
135
136 This sets the pattern string to \c{a pattern}. You can also use the
137 setPattern() function to set a pattern on an existing QRegularExpression
138 object:
139
140 \snippet code/src_corelib_tools_qregularexpression.cpp 1
141
142 Note that due to C++ literal strings rules, you must escape all backslashes
143 inside the pattern string with another backslash:
144
145 \snippet code/src_corelib_tools_qregularexpression.cpp 2
146
147 The pattern() function returns the pattern that is currently set for a
148 QRegularExpression object:
149
150 \snippet code/src_corelib_tools_qregularexpression.cpp 3
151
152 \section1 Pattern Options
153
154 The meaning of the pattern string can be modified by setting one or more
155 \e{pattern options}. For instance, it is possible to set a pattern to match
156 case insensitively by setting the QRegularExpression::CaseInsensitiveOption.
157
158 You can set the options by passing them to the QRegularExpression
159 constructor, as in:
160
161 \snippet code/src_corelib_tools_qregularexpression.cpp 4
162
163 Alternatively, you can use the setPatternOptions() function on an existing
164 QRegularExpressionObject:
165
166 \snippet code/src_corelib_tools_qregularexpression.cpp 5
167
168 It is possible to get the pattern options currently set on a
169 QRegularExpression object by using the patternOptions() function:
170
171 \snippet code/src_corelib_tools_qregularexpression.cpp 6
172
173 Please refer to the QRegularExpression::PatternOption enum documentation for
174 more information about each pattern option.
175
176 \section1 Match Type and Match Options
177
178 The last two arguments of the match() and the globalMatch() functions set
179 the match type and the match options. The match type is a value of the
180 QRegularExpression::MatchType enum; the "traditional" matching algorithm is
181 chosen by using the NormalMatch match type (the default). It is also
182 possible to enable partial matching of the regular expression against a
183 subject string: see the \l{partial matching} section for more details.
184
185 The match options are a set of one or more QRegularExpression::MatchOption
186 values. They change the way a specific match of a regular expression
187 against a subject string is done. Please refer to the
188 QRegularExpression::MatchOption enum documentation for more details.
189
190 \target normal matching
191 \section1 Normal Matching
192
193 In order to perform a match you can simply invoke the match() function
194 passing a string to match against. We refer to this string as the
195 \e{subject string}. The result of the match() function is a
196 QRegularExpressionMatch object that can be used to inspect the results of
197 the match. For instance:
198
199 \snippet code/src_corelib_tools_qregularexpression.cpp 7
200
201 If a match is successful, the (implicit) capturing group number 0 can be
202 used to retrieve the substring matched by the entire pattern (see also the
203 section about \l{extracting captured substrings}):
204
205 \snippet code/src_corelib_tools_qregularexpression.cpp 8
206
207 It's also possible to start a match at an arbitrary offset inside the
208 subject string by passing the offset as an argument of the
209 match() function. In the following example \c{"12 abc"}
210 is not matched because the match is started at offset 1:
211
212 \snippet code/src_corelib_tools_qregularexpression.cpp 9
213
214 \target extracting captured substrings
215 \section2 Extracting captured substrings
216
217 The QRegularExpressionMatch object contains also information about the
218 substrings captured by the capturing groups in the pattern string. The
219 \l{QRegularExpressionMatch::}{captured()} function will return the string
220 captured by the n-th capturing group:
221
222 \snippet code/src_corelib_tools_qregularexpression.cpp 10
223
224 Capturing groups in the pattern are numbered starting from 1, and the
225 implicit capturing group 0 is used to capture the substring that matched
226 the entire pattern.
227
228 It's also possible to retrieve the starting and the ending offsets (inside
229 the subject string) of each captured substring, by using the
230 \l{QRegularExpressionMatch::}{capturedStart()} and the
231 \l{QRegularExpressionMatch::}{capturedEnd()} functions:
232
233 \snippet code/src_corelib_tools_qregularexpression.cpp 11
234
235 All of these functions have an overload taking a QString as a parameter
236 in order to extract \e{named} captured substrings. For instance:
237
238 \snippet code/src_corelib_tools_qregularexpression.cpp 12
239
240 \target global matching
241 \section1 Global Matching
242
243 \e{Global matching} is useful to find all the occurrences of a given
244 regular expression inside a subject string. Suppose that we want to extract
245 all the words from a given string, where a word is a substring matching
246 the pattern \c{\w+}.
247
248 QRegularExpression::globalMatch returns a QRegularExpressionMatchIterator,
249 which is a Java-like forward iterator that can be used to iterate over the
250 results. For instance:
251
252 \snippet code/src_corelib_tools_qregularexpression.cpp 13
253
254 Since it's a Java-like iterator, the QRegularExpressionMatchIterator will
255 point immediately before the first result. Every result is returned as a
256 QRegularExpressionMatch object. The
257 \l{QRegularExpressionMatchIterator::}{hasNext()} function will return true
258 if there's at least one more result, and
259 \l{QRegularExpressionMatchIterator::}{next()} will return the next result
260 and advance the iterator. Continuing from the previous example:
261
262 \snippet code/src_corelib_tools_qregularexpression.cpp 14
263
264 You can also use \l{QRegularExpressionMatchIterator::}{peekNext()} to get
265 the next result without advancing the iterator.
266
267 It is possible to pass a starting offset and one or more match options to
268 the globalMatch() function, exactly like normal matching with match().
269
270 \target partial matching
271 \section1 Partial Matching
272
273 A \e{partial match} is obtained when the end of the subject string is
274 reached, but more characters are needed to successfully complete the match.
275 Note that a partial match is usually much more inefficient than a normal
276 match because many optimizations of the matching algorithm cannot be
277 employed.
278
279 A partial match must be explicitly requested by specifying a match type of
280 PartialPreferCompleteMatch or PartialPreferFirstMatch when calling
281 QRegularExpression::match or QRegularExpression::globalMatch. If a partial
282 match is found, then calling the \l{QRegularExpressionMatch::}{hasMatch()}
283 function on the QRegularExpressionMatch object returned by match() will
284 return \c{false}, but \l{QRegularExpressionMatch::}{hasPartialMatch()} will return
285 \c{true}.
286
287 When a partial match is found, no captured substrings are returned, and the
288 (implicit) capturing group 0 corresponding to the whole match captures the
289 partially matched substring of the subject string.
290
291 Note that asking for a partial match can still lead to a complete match, if
292 one is found; in this case, \l{QRegularExpressionMatch::}{hasMatch()} will
293 return \c{true} and \l{QRegularExpressionMatch::}{hasPartialMatch()}
294 \c{false}. It never happens that a QRegularExpressionMatch reports both a
295 partial and a complete match.
296
297 Partial matching is mainly useful in two scenarios: validating user input
298 in real time and incremental/multi-segment matching.
299
300 \target validating user input
301 \section2 Validating user input
302
303 Suppose that we would like the user to input a date in a specific
304 format, for instance "MMM dd, yyyy". We can check the input validity with
305 a pattern like:
306
307 \c{^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d\d?, \d\d\d\d$}
308
309 (This pattern doesn't catch invalid days, but let's keep it for the
310 example's purposes).
311
312 We would like to validate the input with this regular expression \e{while}
313 the user is typing it, so that we can report an error in the input as soon
314 as it is committed (for instance, the user typed the wrong key). In order
315 to do so we must distinguish three cases:
316
317 \list
318 \li the input cannot possibly match the regular expression;
319 \li the input does match the regular expression;
320 \li the input does not match the regular expression right now,
321 but it will if more characters will be added to it.
322 \endlist
323
324 Note that these three cases represent exactly the possible states of a
325 QValidator (see the QValidator::State enum).
326
327 In particular, in the last case we want the regular expression engine to
328 report a partial match: we are successfully matching the pattern against
329 the subject string but the matching cannot continue because the end of the
330 subject is encountered. Notice, however, that the matching algorithm should
331 continue and try all possibilities, and in case a complete (non-partial)
332 match is found, then this one should be reported, and the input string
333 accepted as fully valid.
334
335 This behavior is implemented by the PartialPreferCompleteMatch match type.
336 For instance:
337
338 \snippet code/src_corelib_tools_qregularexpression.cpp 15
339
340 If matching the same regular expression against the subject string leads to
341 a complete match, it is reported as usual:
342
343 \snippet code/src_corelib_tools_qregularexpression.cpp 16
344
345 Another example with a different pattern, showing the behavior of
346 preferring a complete match over a partial one:
347
348 \snippet code/src_corelib_tools_qregularexpression.cpp 17
349
350 In this case, the subpattern \c{abc\\w+X} partially matches the subject
351 string; however, the subpattern \c{def} matches the subject string
352 completely, and therefore a complete match is reported.
353
354 If multiple partial matches are found when matching (but no complete
355 match), then the QRegularExpressionMatch object will report the first one
356 that is found. For instance:
357
358 \snippet code/src_corelib_tools_qregularexpression.cpp 18
359
360 \section2 Incremental/multi-segment matching
361
362 Incremental matching is another use case of partial matching. Suppose that
363 we want to find the occurrences of a regular expression inside a large text
364 (that is, substrings matching the regular expression). In order to do so we
365 would like to "feed" the large text to the regular expression engines in
366 smaller chunks. The obvious problem is what happens if the substring that
367 matches the regular expression spans across two or more chunks.
368
369 In this case, the regular expression engine should report a partial match,
370 so that we can match again adding new data and (eventually) get a complete
371 match. This implies that the regular expression engine may assume that
372 there are other characters \e{beyond the end} of the subject string. This
373 is not to be taken literally -- the engine will never try to access
374 any character after the last one in the subject.
375
376 QRegularExpression implements this behavior when using the
377 PartialPreferFirstMatch match type. This match type reports a partial match
378 as soon as it is found, and other match alternatives are not tried
379 (even if they could lead to a complete match). For instance:
380
381 \snippet code/src_corelib_tools_qregularexpression.cpp 19
382
383 This happens because when matching the first branch of the alternation
384 operator a partial match is found, and therefore matching stops, without
385 trying the second branch. Another example:
386
387 \snippet code/src_corelib_tools_qregularexpression.cpp 20
388
389 This shows what could seem a counterintuitive behavior of quantifiers:
390 since \c{?} is greedy, then the engine tries first to continue the match
391 after having matched \c{"abc"}; but then the matching reaches the end of the
392 subject string, and therefore a partial match is reported. This is
393 even more surprising in the following example:
394
395 \snippet code/src_corelib_tools_qregularexpression.cpp 21
396
397 It's easy to understand this behavior if we remember that the engine
398 expects the subject string to be only a substring of the whole text we're
399 looking for a match into (that is, how we said before, that the engine
400 assumes that there are other characters beyond the end of the subject
401 string).
402
403 Since the \c{*} quantifier is greedy, then reporting a complete match could
404 be an error, because after the current subject \c{"abc"} there may be other
405 occurrences of \c{"abc"}. For instance, the complete text could have been
406 "abcabcX", and therefore the \e{right} match to report (in the complete
407 text) would have been \c{"abcabc"}; by matching only against the leading
408 \c{"abc"} we instead get a partial match.
409
410 \section1 Error Handling
411
412 It is possible for a QRegularExpression object to be invalid because of
413 syntax errors in the pattern string. The isValid() function will return
414 true if the regular expression is valid, or false otherwise:
415
416 \snippet code/src_corelib_tools_qregularexpression.cpp 22
417
418 You can get more information about the specific error by calling the
419 errorString() function; moreover, the patternErrorOffset() function
420 will return the offset inside the pattern string
421
422 \snippet code/src_corelib_tools_qregularexpression.cpp 23
423
424 If a match is attempted with an invalid QRegularExpression, then the
425 returned QRegularExpressionMatch object will be invalid as well (that is,
426 its \l{QRegularExpressionMatch::}{isValid()} function will return false).
427 The same applies for attempting a global match.
428
429 \section1 Unsupported Perl-compatible Regular Expressions Features
430
431 QRegularExpression does not support all the features available in
432 Perl-compatible regular expressions. The most notable one is the fact that
433 duplicated names for capturing groups are not supported, and using them can
434 lead to undefined behavior.
435
436 This may change in a future version of Qt.
437
438 \section1 Notes for QRegExp Users
439
440 The QRegularExpression class introduced in Qt 5 is a big improvement upon
441 QRegExp, in terms of APIs offered, supported pattern syntax and speed of
442 execution. The biggest difference is that QRegularExpression simply holds a
443 regular expression, and it's \e{not} modified when a match is requested.
444 Instead, a QRegularExpressionMatch object is returned, in order to check
445 the result of a match and extract the captured substring. The same applies
446 with global matching and QRegularExpressionMatchIterator.
447
448 Other differences are outlined below.
449
450 \section2 Different pattern syntax
451
452 Porting a regular expression from QRegExp to QRegularExpression may require
453 changes to the pattern itself.
454
455 In certain scenarios, QRegExp was too lenient and accepted patterns that
456 are simply invalid when using QRegularExpression. These are somehow easy
457 to detect, because the QRegularExpression objects built with these patterns
458 are not valid (cf. isValid()).
459
460 In other cases, a pattern ported from QRegExp to QRegularExpression may
461 silently change semantics. Therefore, it is necessary to review the
462 patterns used. The most notable cases of silent incompatibility are:
463
464 \list
465
466 \li Curly braces are needed in order to use a hexadecimal escape like
467 \c{\xHHHH} with more than 2 digits. A pattern like \c{\x2022} neeeds to
468 be ported to \c{\x{2022}}, or it will match a space (\c{0x20}) followed
469 by the string \c{"22"}. In general, it is highly recommended to always use
470 curly braces with the \c{\x} escape, no matter the amount of digits
471 specified.
472
473 \li A 0-to-n quantification like \c{{,n}} needs to be ported to \c{{0,n}} to
474 preserve semantics. Otherwise, a pattern such as \c{\d{,3}} would
475 actually match a digit followed by the exact string \c{"{,3}"}.
476
477 \li QRegExp by default does Unicode-aware matching, while
478 QRegularExpression requires a separate option; see below for more details.
479
480 \endlist
481
482 \section2 Porting from QRegExp::exactMatch()
483
484 QRegExp::exactMatch() in Qt 4 served two purposes: it exactly matched
485 a regular expression against a subject string, and it implemented partial
486 matching.
487
488 \section3 Porting from QRegExp's Exact Matching
489
490 Exact matching indicates whether the regular expression matches the entire
491 subject string. For example, the classes yield on the subject string \c{"abc123"}:
492
493 \table
494 \header \li \li QRegExp::exactMatch() \li QRegularExpressionMatch::hasMatch()
495 \row \li \c{"\\d+"} \li \b false \li \b true
496 \row \li \c{"[a-z]+\\d+"} \li \b true \li \b true
497 \endtable
498
499 Exact matching is not reflected in QRegularExpression. If you want
500 to be sure that the subject string matches the regular expression
501 exactly, you can wrap the pattern using the anchoredPattern()
502 function:
503
504 \snippet code/src_corelib_tools_qregularexpression.cpp 24
505
506 \section3 Porting from QRegExp's Partial Matching
507
508 When using QRegExp::exactMatch(), if an exact match was not found, one
509 could still find out how much of the subject string was matched by the
510 regular expression by calling QRegExp::matchedLength(). If the returned length
511 was equal to the subject string's length, then one could conclude that a partial
512 match was found.
513
514 QRegularExpression supports partial matching explicitly by means of the
515 appropriate MatchType.
516
517 \section2 Global matching
518
519 Due to limitations of the QRegExp API it was impossible to implement global
520 matching correctly (that is, like Perl does). In particular, patterns that
521 can match 0 characters (like \c{"a*"}) are problematic.
522
523 QRegularExpression::globalMatch() implements Perl global match correctly, and
524 the returned iterator can be used to examine each result.
525
526 \section2 Unicode properties support
527
528 When using QRegExp, character classes such as \c{\w}, \c{\d}, etc. match
529 characters with the corresponding Unicode property: for instance, \c{\d}
530 matches any character with the Unicode Nd (decimal digit) property.
531
532 Those character classes only match ASCII characters by default when using
533 QRegularExpression: for instance, \c{\d} matches exactly a character in the
534 \c{0-9} ASCII range. It is possible to change this behaviour by using the
535 UseUnicodePropertiesOption pattern option.
536
537 \section2 Wildcard matching
538
539 There is no direct way to do wildcard matching in QRegularExpression.
540 However, the wildcardToRegularExpression method is provided to translate
541 glob patterns into a Perl-compatible regular expression that can be used
542 for that purpose.
543
544 \section2 Other pattern syntaxes
545
546 QRegularExpression supports only Perl-compatible regular expressions.
547
548 \section2 Minimal matching
549
550 QRegExp::setMinimal() implemented minimal matching by simply reversing the
551 greediness of the quantifiers (QRegExp did not support lazy quantifiers,
552 like \c{*?}, \c{+?}, etc.). QRegularExpression instead does support greedy,
553 lazy and possessive quantifiers. The InvertedGreedinessOption
554 pattern option can be useful to emulate the effects of QRegExp::setMinimal():
555 if enabled, it inverts the greediness of quantifiers (greedy ones become
556 lazy and vice versa).
557
558 \section2 Caret modes
559
560 The AnchoredMatchOption match option can be used to emulate the
561 QRegExp::CaretAtOffset behaviour. There is no equivalent for the other
562 QRegExp::CaretMode modes.
563
564 \section1 Debugging Code that Uses QRegularExpression
565
566 QRegularExpression internally uses a just in time compiler (JIT) to
567 optimize the execution of the matching algorithm. The JIT makes extensive
568 usage of self-modifying code, which can lead debugging tools such as
569 Valgrind to crash. You must enable all checks for self-modifying code if
570 you want to debug programs using QRegularExpression (for instance, Valgrind's
571 \c{--smc-check} command line option). The downside of enabling such checks
572 is that your program will run considerably slower.
573
574 To avoid that, the JIT is disabled by default if you compile Qt in debug
575 mode. It is possible to override the default and enable or disable the JIT
576 usage (both in debug or release mode) by setting the
577 \c{QT_ENABLE_REGEXP_JIT} environment variable to a non-zero or zero value
578 respectively.
579
580 \sa QRegularExpressionMatch, QRegularExpressionMatchIterator
581*/
582
583/*!
584 \class QRegularExpressionMatch
585 \inmodule QtCore
586 \reentrant
587
588 \brief The QRegularExpressionMatch class provides the results of a matching
589 a QRegularExpression against a string.
590
591 \since 5.0
592
593 \ingroup tools
594 \ingroup shared
595
596 \keyword regular expression match
597
598 A QRegularExpressionMatch object can be obtained by calling the
599 QRegularExpression::match() function, or as a single result of a global
600 match from a QRegularExpressionMatchIterator.
601
602 The success or the failure of a match attempt can be inspected by calling
603 the hasMatch() function. QRegularExpressionMatch also reports a successful
604 partial match through the hasPartialMatch() function.
605
606 In addition, QRegularExpressionMatch returns the substrings captured by the
607 capturing groups in the pattern string. The implicit capturing group with
608 index 0 captures the result of the whole match. The captured() function
609 returns each substring captured, either by the capturing group's index or
610 by its name:
611
612 \snippet code/src_corelib_tools_qregularexpression.cpp 29
613
614 For each captured substring it is possible to query its starting and ending
615 offsets in the subject string by calling the capturedStart() and the
616 capturedEnd() function, respectively. The length of each captured
617 substring is available using the capturedLength() function.
618
619 The convenience function capturedTexts() will return \e{all} the captured
620 substrings at once (including the substring matched by the entire pattern)
621 in the order they have been captured by capturing groups; that is,
622 \c{captured(i) == capturedTexts().at(i)}.
623
624 You can retrieve the QRegularExpression object the subject string was
625 matched against by calling the regularExpression() function; the
626 match type and the match options are available as well by calling
627 the matchType() and the matchOptions() respectively.
628
629 Please refer to the QRegularExpression documentation for more information
630 about the Qt regular expression classes.
631
632 \sa QRegularExpression
633*/
634
635/*!
636 \class QRegularExpressionMatchIterator
637 \inmodule QtCore
638 \reentrant
639
640 \brief The QRegularExpressionMatchIterator class provides an iterator on
641 the results of a global match of a QRegularExpression object against a string.
642
643 \since 5.0
644
645 \ingroup tools
646 \ingroup shared
647
648 \keyword regular expression iterator
649
650 A QRegularExpressionMatchIterator object is a forward only Java-like
651 iterator; it can be obtained by calling the
652 QRegularExpression::globalMatch() function. A new
653 QRegularExpressionMatchIterator will be positioned before the first result.
654 You can then call the hasNext() function to check if there are more
655 results available; if so, the next() function will return the next
656 result and advance the iterator.
657
658 Each result is a QRegularExpressionMatch object holding all the information
659 for that result (including captured substrings).
660
661 For instance:
662
663 \snippet code/src_corelib_tools_qregularexpression.cpp 30
664
665 Moreover, QRegularExpressionMatchIterator offers a peekNext() function
666 to get the next result \e{without} advancing the iterator.
667
668 You can retrieve the QRegularExpression object the subject string was
669 matched against by calling the regularExpression() function; the
670 match type and the match options are available as well by calling
671 the matchType() and the matchOptions() respectively.
672
673 Please refer to the QRegularExpression documentation for more information
674 about the Qt regular expression classes.
675
676 \sa QRegularExpression, QRegularExpressionMatch
677*/
678
679
680/*!
681 \enum QRegularExpression::PatternOption
682
683 The PatternOption enum defines modifiers to the way the pattern string
684 should be interpreted, and therefore the way the pattern matches against a
685 subject string.
686
687 \value NoPatternOption
688 No pattern options are set.
689
690 \value CaseInsensitiveOption
691 The pattern should match against the subject string in a case
692 insensitive way. This option corresponds to the /i modifier in Perl
693 regular expressions.
694
695 \value DotMatchesEverythingOption
696 The dot metacharacter (\c{.}) in the pattern string is allowed to match
697 any character in the subject string, including newlines (normally, the
698 dot does not match newlines). This option corresponds to the \c{/s}
699 modifier in Perl regular expressions.
700
701 \value MultilineOption
702 The caret (\c{^}) and the dollar (\c{$}) metacharacters in the pattern
703 string are allowed to match, respectively, immediately after and
704 immediately before any newline in the subject string, as well as at the
705 very beginning and at the very end of the subject string. This option
706 corresponds to the \c{/m} modifier in Perl regular expressions.
707
708 \value ExtendedPatternSyntaxOption
709 Any whitespace in the pattern string which is not escaped and outside a
710 character class is ignored. Moreover, an unescaped sharp (\b{#})
711 outside a character class causes all the following characters, until
712 the first newline (included), to be ignored. This can be used to
713 increase the readability of a pattern string as well as put comments
714 inside regular expressions; this is particularly useful if the pattern
715 string is loaded from a file or written by the user, because in C++
716 code it is always possible to use the rules for string literals to put
717 comments outside the pattern string. This option corresponds to the \c{/x}
718 modifier in Perl regular expressions.
719
720 \value InvertedGreedinessOption
721 The greediness of the quantifiers is inverted: \c{*}, \c{+}, \c{?},
722 \c{{m,n}}, etc. become lazy, while their lazy versions (\c{*?},
723 \c{+?}, \c{??}, \c{{m,n}?}, etc.) become greedy. There is no equivalent
724 for this option in Perl regular expressions.
725
726 \value DontCaptureOption
727 The non-named capturing groups do not capture substrings; named
728 capturing groups still work as intended, as well as the implicit
729 capturing group number 0 corresponding to the entire match. There is no
730 equivalent for this option in Perl regular expressions.
731
732 \value UseUnicodePropertiesOption
733 The meaning of the \c{\w}, \c{\d}, etc., character classes, as well as
734 the meaning of their counterparts (\c{\W}, \c{\D}, etc.), is changed
735 from matching ASCII characters only to matching any character with the
736 corresponding Unicode property. For instance, \c{\d} is changed to
737 match any character with the Unicode Nd (decimal digit) property;
738 \c{\w} to match any character with either the Unicode L (letter) or N
739 (digit) property, plus underscore, and so on. This option corresponds
740 to the \c{/u} modifier in Perl regular expressions.
741
742 \value OptimizeOnFirstUsageOption
743 This option is ignored. A regular expression is automatically optimized
744 (including JIT compiling) the first time it is used. This enum value
745 was introduced in Qt 5.4.
746
747 \value DontAutomaticallyOptimizeOption
748 This option is ignored. A regular expression is automatically optimized
749 (including JIT compiling) the first time it is used. This enum value
750 was introduced in Qt 5.4.
751*/
752
753/*!
754 \enum QRegularExpression::MatchType
755
756 The MatchType enum defines the type of the match that should be attempted
757 against the subject string.
758
759 \value NormalMatch
760 A normal match is done.
761
762 \value PartialPreferCompleteMatch
763 The pattern string is matched partially against the subject string. If
764 a partial match is found, then it is recorded, and other matching
765 alternatives are tried as usual. If a complete match is then found,
766 then it's preferred to the partial match; in this case only the
767 complete match is reported. If instead no complete match is found (but
768 only the partial one), then the partial one is reported.
769
770 \value PartialPreferFirstMatch
771 The pattern string is matched partially against the subject string. If
772 a partial match is found, then matching stops and the partial match is
773 reported. In this case, other matching alternatives (potentially
774 leading to a complete match) are not tried. Moreover, this match type
775 assumes that the subject string only a substring of a larger text, and
776 that (in this text) there are other characters beyond the end of the
777 subject string. This can lead to surprising results; see the discussion
778 in the \l{partial matching} section for more details.
779
780 \value NoMatch
781 No matching is done. This value is returned as the match type by a
782 default constructed QRegularExpressionMatch or
783 QRegularExpressionMatchIterator. Using this match type is not very
784 useful for the user, as no matching ever happens. This enum value
785 has been introduced in Qt 5.1.
786*/
787
788/*!
789 \enum QRegularExpression::MatchOption
790
791 \value NoMatchOption
792 No match options are set.
793
794 \value AnchoredMatchOption
795 The match is constrained to start exactly at the offset passed to
796 match() in order to be successful, even if the pattern string does not
797 contain any metacharacter that anchors the match at that point.
798
799 \value DontCheckSubjectStringMatchOption
800 The subject string is not checked for UTF-16 validity before
801 attempting a match. Use this option with extreme caution, as
802 attempting to match an invalid string may crash the program and/or
803 constitute a security issue. This enum value has been introduced in
804 Qt 5.4.
805*/
806
807/*!
808 \internal
809*/
810static int convertToPcreOptions(QRegularExpression::PatternOptions patternOptions)
811{
812 int options = 0;
813
814 if (patternOptions & QRegularExpression::CaseInsensitiveOption)
815 options |= PCRE2_CASELESS;
816 if (patternOptions & QRegularExpression::DotMatchesEverythingOption)
817 options |= PCRE2_DOTALL;
818 if (patternOptions & QRegularExpression::MultilineOption)
819 options |= PCRE2_MULTILINE;
820 if (patternOptions & QRegularExpression::ExtendedPatternSyntaxOption)
821 options |= PCRE2_EXTENDED;
822 if (patternOptions & QRegularExpression::InvertedGreedinessOption)
823 options |= PCRE2_UNGREEDY;
824 if (patternOptions & QRegularExpression::DontCaptureOption)
825 options |= PCRE2_NO_AUTO_CAPTURE;
826 if (patternOptions & QRegularExpression::UseUnicodePropertiesOption)
827 options |= PCRE2_UCP;
828
829 return options;
830}
831
832/*!
833 \internal
834*/
835static int convertToPcreOptions(QRegularExpression::MatchOptions matchOptions)
836{
837 int options = 0;
838
839 if (matchOptions & QRegularExpression::AnchoredMatchOption)
840 options |= PCRE2_ANCHORED;
841 if (matchOptions & QRegularExpression::DontCheckSubjectStringMatchOption)
842 options |= PCRE2_NO_UTF_CHECK;
843
844 return options;
845}
846
847struct QRegularExpressionPrivate : QSharedData
848{
849 QRegularExpressionPrivate();
850 ~QRegularExpressionPrivate();
851 QRegularExpressionPrivate(const QRegularExpressionPrivate &other);
852
853 void cleanCompiledPattern();
854 void compilePattern();
855 void getPatternInfo();
856 void optimizePattern();
857
858 enum CheckSubjectStringOption {
859 CheckSubjectString,
860 DontCheckSubjectString
861 };
862
863 QRegularExpressionMatchPrivate *doMatch(const QString &subject,
864 int subjectStartPos,
865 int subjectLength,
866 int offset,
867 QRegularExpression::MatchType matchType,
868 QRegularExpression::MatchOptions matchOptions,
869 CheckSubjectStringOption checkSubjectStringOption = CheckSubjectString,
870 const QRegularExpressionMatchPrivate *previous = nullptr) const;
871
872 int captureIndexForName(QStringView name) const;
873
874 // sizeof(QSharedData) == 4, so start our members with an enum
875 QRegularExpression::PatternOptions patternOptions;
876 QString pattern;
877
878 // *All* of the following members are managed while holding this mutex,
879 // except for isDirty which is set to true by QRegularExpression setters
880 // (right after a detach happened).
881 mutable QMutex mutex;
882
883 // The PCRE code pointer is reference-counted by the QRegularExpressionPrivate
884 // objects themselves; when the private is copied (i.e. a detach happened)
885 // it is set to nullptr
886 pcre2_code_16 *compiledPattern;
887 int errorCode;
888 int errorOffset;
889 int capturingCount;
890 bool usingCrLfNewlines;
891 bool isDirty;
892};
893
894struct QRegularExpressionMatchPrivate : QSharedData
895{
896 QRegularExpressionMatchPrivate(const QRegularExpression &re,
897 const QString &subject,
898 int subjectStart,
899 int subjectLength,
900 QRegularExpression::MatchType matchType,
901 QRegularExpression::MatchOptions matchOptions);
902
903 QRegularExpressionMatch nextMatch() const;
904
905 const QRegularExpression regularExpression;
906 const QString subject;
907 // the capturedOffsets vector contains pairs of (start, end) positions
908 // for each captured substring
909 QVector<int> capturedOffsets;
910
911 const int subjectStart;
912 const int subjectLength;
913
914 const QRegularExpression::MatchType matchType;
915 const QRegularExpression::MatchOptions matchOptions;
916
917 int capturedCount;
918
919 bool hasMatch;
920 bool hasPartialMatch;
921 bool isValid;
922};
923
924struct QRegularExpressionMatchIteratorPrivate : QSharedData
925{
926 QRegularExpressionMatchIteratorPrivate(const QRegularExpression &re,
927 QRegularExpression::MatchType matchType,
928 QRegularExpression::MatchOptions matchOptions,
929 const QRegularExpressionMatch &next);
930
931 bool hasNext() const;
932 QRegularExpressionMatch next;
933 const QRegularExpression regularExpression;
934 const QRegularExpression::MatchType matchType;
935 const QRegularExpression::MatchOptions matchOptions;
936};
937
938/*!
939 \internal
940*/
941QRegularExpression::QRegularExpression(QRegularExpressionPrivate &dd)
942 : d(&dd)
943{
944}
945
946/*!
947 \internal
948*/
949QRegularExpressionPrivate::QRegularExpressionPrivate()
950 : QSharedData(),
951 patternOptions(),
952 pattern(),
953 mutex(),
954 compiledPattern(nullptr),
955 errorCode(0),
956 errorOffset(-1),
957 capturingCount(0),
958 usingCrLfNewlines(false),
959 isDirty(true)
960{
961}
962
963/*!
964 \internal
965*/
966QRegularExpressionPrivate::~QRegularExpressionPrivate()
967{
968 cleanCompiledPattern();
969}
970
971/*!
972 \internal
973
974 Copies the private, which means copying only the pattern and the pattern
975 options. The compiledPattern pointer is NOT copied (we
976 do not own it any more), and in general all the members set when
977 compiling a pattern are set to default values. isDirty is set back to true
978 so that the pattern has to be recompiled again.
979*/
980QRegularExpressionPrivate::QRegularExpressionPrivate(const QRegularExpressionPrivate &other)
981 : QSharedData(other),
982 patternOptions(other.patternOptions),
983 pattern(other.pattern),
984 mutex(),
985 compiledPattern(nullptr),
986 errorCode(0),
987 errorOffset(-1),
988 capturingCount(0),
989 usingCrLfNewlines(false),
990 isDirty(true)
991{
992}
993
994/*!
995 \internal
996*/
997void QRegularExpressionPrivate::cleanCompiledPattern()
998{
999 pcre2_code_free_16(compiledPattern);
1000 compiledPattern = nullptr;
1001 errorCode = 0;
1002 errorOffset = -1;
1003 capturingCount = 0;
1004 usingCrLfNewlines = false;
1005}
1006
1007/*!
1008 \internal
1009*/
1010void QRegularExpressionPrivate::compilePattern()
1011{
1012 const QMutexLocker lock(&mutex);
1013
1014 if (!isDirty)
1015 return;
1016
1017 isDirty = false;
1018 cleanCompiledPattern();
1019
1020 int options = convertToPcreOptions(patternOptions);
1021 options |= PCRE2_UTF;
1022
1023 PCRE2_SIZE patternErrorOffset;
1024 compiledPattern = pcre2_compile_16(pattern.utf16(),
1025 pattern.length(),
1026 options,
1027 &errorCode,
1028 &patternErrorOffset,
1029 nullptr);
1030
1031 if (!compiledPattern) {
1032 errorOffset = static_cast<int>(patternErrorOffset);
1033 return;
1034 } else {
1035 // ignore whatever PCRE2 wrote into errorCode -- leave it to 0 to mean "no error"
1036 errorCode = 0;
1037 }
1038
1039 optimizePattern();
1040 getPatternInfo();
1041}
1042
1043/*!
1044 \internal
1045*/
1046void QRegularExpressionPrivate::getPatternInfo()
1047{
1048 Q_ASSERT(compiledPattern);
1049
1050 pcre2_pattern_info_16(compiledPattern, PCRE2_INFO_CAPTURECOUNT, &capturingCount);
1051
1052 // detect the settings for the newline
1053 unsigned int patternNewlineSetting;
1054 if (pcre2_pattern_info_16(compiledPattern, PCRE2_INFO_NEWLINE, &patternNewlineSetting) != 0) {
1055 // no option was specified in the regexp, grab PCRE build defaults
1056 pcre2_config_16(PCRE2_CONFIG_NEWLINE, &patternNewlineSetting);
1057 }
1058
1059 usingCrLfNewlines = (patternNewlineSetting == PCRE2_NEWLINE_CRLF) ||
1060 (patternNewlineSetting == PCRE2_NEWLINE_ANY) ||
1061 (patternNewlineSetting == PCRE2_NEWLINE_ANYCRLF);
1062
1063 unsigned int hasJOptionChanged;
1064 pcre2_pattern_info_16(compiledPattern, PCRE2_INFO_JCHANGED, &hasJOptionChanged);
1065 if (Q_UNLIKELY(hasJOptionChanged)) {
1066 qWarning(msg: "QRegularExpressionPrivate::getPatternInfo(): the pattern '%ls'\n is using the (?J) option; duplicate capturing group names are not supported by Qt",
1067 qUtf16Printable(pattern));
1068 }
1069}
1070
1071
1072/*
1073 Simple "smartpointer" wrapper around a pcre2_jit_stack_16, to be used with
1074 QThreadStorage.
1075*/
1076class QPcreJitStackPointer
1077{
1078 Q_DISABLE_COPY(QPcreJitStackPointer)
1079
1080public:
1081 /*!
1082 \internal
1083 */
1084 QPcreJitStackPointer()
1085 {
1086 // The default JIT stack size in PCRE is 32K,
1087 // we allocate from 32K up to 512K.
1088 stack = pcre2_jit_stack_create_16(32 * 1024, 512 * 1024, nullptr);
1089 }
1090 /*!
1091 \internal
1092 */
1093 ~QPcreJitStackPointer()
1094 {
1095 if (stack)
1096 pcre2_jit_stack_free_16(stack);
1097 }
1098
1099 pcre2_jit_stack_16 *stack;
1100};
1101
1102Q_GLOBAL_STATIC(QThreadStorage<QPcreJitStackPointer *>, jitStacks)
1103
1104/*!
1105 \internal
1106*/
1107static pcre2_jit_stack_16 *qtPcreCallback(void *)
1108{
1109 if (jitStacks()->hasLocalData())
1110 return jitStacks()->localData()->stack;
1111
1112 return nullptr;
1113}
1114
1115/*!
1116 \internal
1117*/
1118static bool isJitEnabled()
1119{
1120 QByteArray jitEnvironment = qgetenv(varName: "QT_ENABLE_REGEXP_JIT");
1121 if (!jitEnvironment.isEmpty()) {
1122 bool ok;
1123 int enableJit = jitEnvironment.toInt(ok: &ok);
1124 return ok ? (enableJit != 0) : true;
1125 }
1126
1127#ifdef QT_DEBUG
1128 return false;
1129#elif defined(Q_OS_MACOS)
1130 return !qt_mac_runningUnderRosetta();
1131#else
1132 return true;
1133#endif
1134}
1135
1136/*!
1137 \internal
1138
1139 The purpose of the function is to call pcre2_jit_compile_16, which
1140 JIT-compiles the pattern.
1141
1142 It gets called when a pattern is recompiled by us (in compilePattern()),
1143 under mutex protection.
1144*/
1145void QRegularExpressionPrivate::optimizePattern()
1146{
1147 Q_ASSERT(compiledPattern);
1148
1149 static const bool enableJit = isJitEnabled();
1150
1151 if (!enableJit)
1152 return;
1153
1154 pcre2_jit_compile_16(compiledPattern, PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_PARTIAL_HARD);
1155}
1156
1157/*!
1158 \internal
1159
1160 Returns the capturing group number for the given name. Duplicated names for
1161 capturing groups are not supported.
1162*/
1163int QRegularExpressionPrivate::captureIndexForName(QStringView name) const
1164{
1165 Q_ASSERT(!name.isEmpty());
1166
1167 if (!compiledPattern)
1168 return -1;
1169
1170 // See the other usages of pcre2_pattern_info_16 for more details about this
1171 PCRE2_SPTR16 *namedCapturingTable;
1172 unsigned int namedCapturingTableEntryCount;
1173 unsigned int namedCapturingTableEntrySize;
1174
1175 pcre2_pattern_info_16(compiledPattern, PCRE2_INFO_NAMETABLE, &namedCapturingTable);
1176 pcre2_pattern_info_16(compiledPattern, PCRE2_INFO_NAMECOUNT, &namedCapturingTableEntryCount);
1177 pcre2_pattern_info_16(compiledPattern, PCRE2_INFO_NAMEENTRYSIZE, &namedCapturingTableEntrySize);
1178
1179 for (unsigned int i = 0; i < namedCapturingTableEntryCount; ++i) {
1180 const auto currentNamedCapturingTableRow =
1181 reinterpret_cast<const char16_t *>(namedCapturingTable) + namedCapturingTableEntrySize * i;
1182
1183 if (name == (currentNamedCapturingTableRow + 1)) {
1184 const int index = *currentNamedCapturingTableRow;
1185 return index;
1186 }
1187 }
1188
1189 return -1;
1190}
1191
1192/*!
1193 \internal
1194
1195 This is a simple wrapper for pcre2_match_16 for handling the case in which the
1196 JIT runs out of memory. In that case, we allocate a thread-local JIT stack
1197 and re-run pcre2_match_16.
1198*/
1199static int safe_pcre2_match_16(const pcre2_code_16 *code,
1200 const unsigned short *subject, int length,
1201 int startOffset, int options,
1202 pcre2_match_data_16 *matchData,
1203 pcre2_match_context_16 *matchContext)
1204{
1205 int result = pcre2_match_16(code, subject, length,
1206 startOffset, options, matchData, matchContext);
1207
1208 if (result == PCRE2_ERROR_JIT_STACKLIMIT && !jitStacks()->hasLocalData()) {
1209 QPcreJitStackPointer *p = new QPcreJitStackPointer;
1210 jitStacks()->setLocalData(p);
1211
1212 result = pcre2_match_16(code, subject, length,
1213 startOffset, options, matchData, matchContext);
1214 }
1215
1216 return result;
1217}
1218
1219/*!
1220 \internal
1221
1222 Performs a match on the substring of the given \a subject string,
1223 substring which starts from \a subjectStart and up to
1224 (but not including) \a subjectStart + \a subjectLength. The match
1225 will be of type \a matchType and using the options \a matchOptions;
1226 the matching \a offset is relative the substring,
1227 and if negative, it's taken as an offset from the end of the substring.
1228
1229 It also advances a match if a previous result is given as \a
1230 previous. The \a subject string goes a Unicode validity check if
1231 \a checkSubjectString is CheckSubjectString and the match options don't
1232 include DontCheckSubjectStringMatchOption (PCRE doesn't like illegal
1233 UTF-16 sequences).
1234
1235 Returns the QRegularExpressionMatchPrivate of the result.
1236
1237 Advancing a match is a tricky algorithm. If the previous match matched a
1238 non-empty string, we just do an ordinary match at the offset position.
1239
1240 If the previous match matched an empty string, then an anchored, non-empty
1241 match is attempted at the offset position. If that succeeds, then we got
1242 the next match and we can return it. Otherwise, we advance by 1 position
1243 (which can be one or two code units in UTF-16!) and reattempt a "normal"
1244 match. We also have the problem of detecting the current newline format: if
1245 the new advanced offset is pointing to the beginning of a CRLF sequence, we
1246 must advance over it.
1247*/
1248QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString &subject,
1249 int subjectStart,
1250 int subjectLength,
1251 int offset,
1252 QRegularExpression::MatchType matchType,
1253 QRegularExpression::MatchOptions matchOptions,
1254 CheckSubjectStringOption checkSubjectStringOption,
1255 const QRegularExpressionMatchPrivate *previous) const
1256{
1257 if (offset < 0)
1258 offset += subjectLength;
1259
1260 QRegularExpression re(*const_cast<QRegularExpressionPrivate *>(this));
1261
1262 QRegularExpressionMatchPrivate *priv = new QRegularExpressionMatchPrivate(re, subject,
1263 subjectStart, subjectLength,
1264 matchType, matchOptions);
1265
1266 if (offset < 0 || offset > subjectLength)
1267 return priv;
1268
1269 if (Q_UNLIKELY(!compiledPattern)) {
1270 qWarning(msg: "QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object");
1271 return priv;
1272 }
1273
1274 // skip doing the actual matching if NoMatch type was requested
1275 if (matchType == QRegularExpression::NoMatch) {
1276 priv->isValid = true;
1277 return priv;
1278 }
1279
1280 int pcreOptions = convertToPcreOptions(matchOptions);
1281
1282 if (matchType == QRegularExpression::PartialPreferCompleteMatch)
1283 pcreOptions |= PCRE2_PARTIAL_SOFT;
1284 else if (matchType == QRegularExpression::PartialPreferFirstMatch)
1285 pcreOptions |= PCRE2_PARTIAL_HARD;
1286
1287 if (checkSubjectStringOption == DontCheckSubjectString)
1288 pcreOptions |= PCRE2_NO_UTF_CHECK;
1289
1290 bool previousMatchWasEmpty = false;
1291 if (previous && previous->hasMatch &&
1292 (previous->capturedOffsets.at(i: 0) == previous->capturedOffsets.at(i: 1))) {
1293 previousMatchWasEmpty = true;
1294 }
1295
1296 pcre2_match_context_16 *matchContext = pcre2_match_context_create_16(nullptr);
1297 pcre2_jit_stack_assign_16(matchContext, &qtPcreCallback, nullptr);
1298 pcre2_match_data_16 *matchData = pcre2_match_data_create_from_pattern_16(compiledPattern, nullptr);
1299
1300 const auto subjectUtf16 = reinterpret_cast<const ushort*>(subject.data()) + subjectStart;
1301
1302 int result;
1303
1304 if (!previousMatchWasEmpty) {
1305 result = safe_pcre2_match_16(code: compiledPattern,
1306 subject: subjectUtf16, length: subjectLength,
1307 startOffset: offset, options: pcreOptions,
1308 matchData, matchContext);
1309 } else {
1310 result = safe_pcre2_match_16(code: compiledPattern,
1311 subject: subjectUtf16, length: subjectLength,
1312 startOffset: offset, options: pcreOptions | PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED,
1313 matchData, matchContext);
1314
1315 if (result == PCRE2_ERROR_NOMATCH) {
1316 ++offset;
1317
1318 if (usingCrLfNewlines
1319 && offset < subjectLength
1320 && subjectUtf16[offset - 1] == QLatin1Char('\r')
1321 && subjectUtf16[offset] == QLatin1Char('\n')) {
1322 ++offset;
1323 } else if (offset < subjectLength
1324 && QChar::isLowSurrogate(ucs4: subjectUtf16[offset])) {
1325 ++offset;
1326 }
1327
1328 result = safe_pcre2_match_16(code: compiledPattern,
1329 subject: subjectUtf16, length: subjectLength,
1330 startOffset: offset, options: pcreOptions,
1331 matchData, matchContext);
1332 }
1333 }
1334
1335#ifdef QREGULAREXPRESSION_DEBUG
1336 qDebug() << "Matching" << pattern << "against" << subject
1337 << "starting at" << subjectStart << "len" << subjectLength
1338 << "offset" << offset
1339 << matchType << matchOptions << previousMatchWasEmpty
1340 << "result" << result;
1341#endif
1342
1343 // result == 0 means not enough space in captureOffsets; should never happen
1344 Q_ASSERT(result != 0);
1345
1346 if (result > 0) {
1347 // full match
1348 priv->isValid = true;
1349 priv->hasMatch = true;
1350 priv->capturedCount = result;
1351 priv->capturedOffsets.resize(asize: result * 2);
1352 } else {
1353 // no match, partial match or error
1354 priv->hasPartialMatch = (result == PCRE2_ERROR_PARTIAL);
1355 priv->isValid = (result == PCRE2_ERROR_NOMATCH || result == PCRE2_ERROR_PARTIAL);
1356
1357 if (result == PCRE2_ERROR_PARTIAL) {
1358 // partial match:
1359 // leave the start and end capture offsets (i.e. cap(0))
1360 priv->capturedCount = 1;
1361 priv->capturedOffsets.resize(asize: 2);
1362 } else {
1363 // no match or error
1364 priv->capturedCount = 0;
1365 priv->capturedOffsets.clear();
1366 }
1367 }
1368
1369 // copy the captured substrings offsets, if any
1370 if (priv->capturedCount) {
1371 PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_16(matchData);
1372 int * const capturedOffsets = priv->capturedOffsets.data();
1373
1374 for (int i = 0; i < priv->capturedCount * 2; ++i)
1375 capturedOffsets[i] = static_cast<int>(ovector[i]);
1376
1377 // For partial matches, PCRE2 and PCRE1 differ in behavior when lookbehinds
1378 // are involved. PCRE2 reports the real begin of the match and the maximum
1379 // used lookbehind as distinct information; PCRE1 instead automatically
1380 // adjusted ovector[0] to include the maximum lookbehind.
1381 //
1382 // For instance, given the pattern "\bstring\b", and the subject "a str":
1383 // * PCRE1 reports partial, capturing " str"
1384 // * PCRE2 reports partial, capturing "str" with a lookbehind of 1
1385 //
1386 // To keep behavior, emulate PCRE1 here.
1387 // (Eventually, we could expose the lookbehind info in a future patch.)
1388 if (result == PCRE2_ERROR_PARTIAL) {
1389 unsigned int maximumLookBehind;
1390 pcre2_pattern_info_16(compiledPattern, PCRE2_INFO_MAXLOOKBEHIND, &maximumLookBehind);
1391 capturedOffsets[0] -= maximumLookBehind;
1392 }
1393 }
1394
1395 pcre2_match_data_free_16(matchData);
1396 pcre2_match_context_free_16(matchContext);
1397
1398 return priv;
1399}
1400
1401/*!
1402 \internal
1403*/
1404QRegularExpressionMatchPrivate::QRegularExpressionMatchPrivate(const QRegularExpression &re,
1405 const QString &subject,
1406 int subjectStart,
1407 int subjectLength,
1408 QRegularExpression::MatchType matchType,
1409 QRegularExpression::MatchOptions matchOptions)
1410 : regularExpression(re), subject(subject),
1411 subjectStart(subjectStart), subjectLength(subjectLength),
1412 matchType(matchType), matchOptions(matchOptions),
1413 capturedCount(0),
1414 hasMatch(false), hasPartialMatch(false), isValid(false)
1415{
1416}
1417
1418
1419/*!
1420 \internal
1421*/
1422QRegularExpressionMatch QRegularExpressionMatchPrivate::nextMatch() const
1423{
1424 Q_ASSERT(isValid);
1425 Q_ASSERT(hasMatch || hasPartialMatch);
1426
1427 // Note the DontCheckSubjectString passed for the check of the subject string:
1428 // if we're advancing a match on the same subject,
1429 // then that subject was already checked at least once (when this object
1430 // was created, or when the object that created this one was created, etc.)
1431 QRegularExpressionMatchPrivate *nextPrivate = regularExpression.d->doMatch(subject,
1432 subjectStart,
1433 subjectLength,
1434 offset: capturedOffsets.at(i: 1),
1435 matchType,
1436 matchOptions,
1437 checkSubjectStringOption: QRegularExpressionPrivate::DontCheckSubjectString,
1438 previous: this);
1439 return QRegularExpressionMatch(*nextPrivate);
1440}
1441
1442/*!
1443 \internal
1444*/
1445QRegularExpressionMatchIteratorPrivate::QRegularExpressionMatchIteratorPrivate(const QRegularExpression &re,
1446 QRegularExpression::MatchType matchType,
1447 QRegularExpression::MatchOptions matchOptions,
1448 const QRegularExpressionMatch &next)
1449 : next(next),
1450 regularExpression(re),
1451 matchType(matchType), matchOptions(matchOptions)
1452{
1453}
1454
1455/*!
1456 \internal
1457*/
1458bool QRegularExpressionMatchIteratorPrivate::hasNext() const
1459{
1460 return next.isValid() && (next.hasMatch() || next.hasPartialMatch());
1461}
1462
1463// PUBLIC API
1464
1465/*!
1466 Constructs a QRegularExpression object with an empty pattern and no pattern
1467 options.
1468
1469 \sa setPattern(), setPatternOptions()
1470*/
1471QRegularExpression::QRegularExpression()
1472 : d(new QRegularExpressionPrivate)
1473{
1474}
1475
1476/*!
1477 Constructs a QRegularExpression object using the given \a pattern as
1478 pattern and the \a options as the pattern options.
1479
1480 \sa setPattern(), setPatternOptions()
1481*/
1482QRegularExpression::QRegularExpression(const QString &pattern, PatternOptions options)
1483 : d(new QRegularExpressionPrivate)
1484{
1485 d->pattern = pattern;
1486 d->patternOptions = options;
1487}
1488
1489/*!
1490 Constructs a QRegularExpression object as a copy of \a re.
1491
1492 \sa operator=()
1493*/
1494QRegularExpression::QRegularExpression(const QRegularExpression &re)
1495 : d(re.d)
1496{
1497}
1498
1499/*!
1500 Destroys the QRegularExpression object.
1501*/
1502QRegularExpression::~QRegularExpression()
1503{
1504}
1505
1506/*!
1507 Assigns the regular expression \a re to this object, and returns a reference
1508 to the copy. Both the pattern and the pattern options are copied.
1509*/
1510QRegularExpression &QRegularExpression::operator=(const QRegularExpression &re)
1511{
1512 d = re.d;
1513 return *this;
1514}
1515
1516/*!
1517 \fn void QRegularExpression::swap(QRegularExpression &other)
1518
1519 Swaps the regular expression \a other with this regular expression. This
1520 operation is very fast and never fails.
1521*/
1522
1523/*!
1524 Returns the pattern string of the regular expression.
1525
1526 \sa setPattern(), patternOptions()
1527*/
1528QString QRegularExpression::pattern() const
1529{
1530 return d->pattern;
1531}
1532
1533/*!
1534 Sets the pattern string of the regular expression to \a pattern. The
1535 pattern options are left unchanged.
1536
1537 \sa pattern(), setPatternOptions()
1538*/
1539void QRegularExpression::setPattern(const QString &pattern)
1540{
1541 d.detach();
1542 d->isDirty = true;
1543 d->pattern = pattern;
1544}
1545
1546/*!
1547 Returns the pattern options for the regular expression.
1548
1549 \sa setPatternOptions(), pattern()
1550*/
1551QRegularExpression::PatternOptions QRegularExpression::patternOptions() const
1552{
1553 return d->patternOptions;
1554}
1555
1556/*!
1557 Sets the given \a options as the pattern options of the regular expression.
1558 The pattern string is left unchanged.
1559
1560 \sa patternOptions(), setPattern()
1561*/
1562void QRegularExpression::setPatternOptions(PatternOptions options)
1563{
1564 d.detach();
1565 d->isDirty = true;
1566 d->patternOptions = options;
1567}
1568
1569/*!
1570 Returns the number of capturing groups inside the pattern string,
1571 or -1 if the regular expression is not valid.
1572
1573 \note The implicit capturing group 0 is \e{not} included in the returned number.
1574
1575 \sa isValid()
1576*/
1577int QRegularExpression::captureCount() const
1578{
1579 if (!isValid()) // will compile the pattern
1580 return -1;
1581 return d->capturingCount;
1582}
1583
1584/*!
1585 \since 5.1
1586
1587 Returns a list of captureCount() + 1 elements, containing the names of the
1588 named capturing groups in the pattern string. The list is sorted such that
1589 the element of the list at position \c{i} is the name of the \c{i}-th
1590 capturing group, if it has a name, or an empty string if that capturing
1591 group is unnamed.
1592
1593 For instance, given the regular expression
1594
1595 \snippet code/src_corelib_tools_qregularexpression.cpp 32
1596
1597 namedCaptureGroups() will return the following list:
1598
1599 \snippet code/src_corelib_tools_qregularexpression.cpp 33
1600
1601 which corresponds to the fact that the capturing group #0 (corresponding to
1602 the whole match) has no name, the capturing group #1 has name "day", the
1603 capturing group #2 has name "month", etc.
1604
1605 If the regular expression is not valid, returns an empty list.
1606
1607 \sa isValid(), QRegularExpressionMatch::captured(), QString::isEmpty()
1608*/
1609QStringList QRegularExpression::namedCaptureGroups() const
1610{
1611 if (!isValid()) // isValid() will compile the pattern
1612 return QStringList();
1613
1614 // namedCapturingTable will point to a table of
1615 // namedCapturingTableEntryCount entries, each one of which
1616 // contains one ushort followed by the name, NUL terminated.
1617 // The ushort is the numerical index of the name in the pattern.
1618 // The length of each entry is namedCapturingTableEntrySize.
1619 PCRE2_SPTR16 *namedCapturingTable;
1620 unsigned int namedCapturingTableEntryCount;
1621 unsigned int namedCapturingTableEntrySize;
1622
1623 pcre2_pattern_info_16(d->compiledPattern, PCRE2_INFO_NAMETABLE, &namedCapturingTable);
1624 pcre2_pattern_info_16(d->compiledPattern, PCRE2_INFO_NAMECOUNT, &namedCapturingTableEntryCount);
1625 pcre2_pattern_info_16(d->compiledPattern, PCRE2_INFO_NAMEENTRYSIZE, &namedCapturingTableEntrySize);
1626
1627 QStringList result;
1628
1629 // no QList::resize nor fill is available. The +1 is for the implicit group #0
1630 result.reserve(alloc: d->capturingCount + 1);
1631 for (int i = 0; i < d->capturingCount + 1; ++i)
1632 result.append(t: QString());
1633
1634 for (unsigned int i = 0; i < namedCapturingTableEntryCount; ++i) {
1635 const ushort * const currentNamedCapturingTableRow =
1636 reinterpret_cast<const ushort *>(namedCapturingTable) + namedCapturingTableEntrySize * i;
1637
1638 const int index = *currentNamedCapturingTableRow;
1639 result[index] = QString::fromUtf16(currentNamedCapturingTableRow + 1);
1640 }
1641
1642 return result;
1643}
1644
1645/*!
1646 Returns \c true if the regular expression is a valid regular expression (that
1647 is, it contains no syntax errors, etc.), or false otherwise. Use
1648 errorString() to obtain a textual description of the error.
1649
1650 \sa errorString(), patternErrorOffset()
1651*/
1652bool QRegularExpression::isValid() const
1653{
1654 d.data()->compilePattern();
1655 return d->compiledPattern;
1656}
1657
1658/*!
1659 Returns a textual description of the error found when checking the validity
1660 of the regular expression, or "no error" if no error was found.
1661
1662 \sa isValid(), patternErrorOffset()
1663*/
1664QString QRegularExpression::errorString() const
1665{
1666 d.data()->compilePattern();
1667 if (d->errorCode) {
1668 QString errorString;
1669 int errorStringLength;
1670 do {
1671 errorString.resize(size: errorString.length() + 64);
1672 errorStringLength = pcre2_get_error_message_16(d->errorCode,
1673 reinterpret_cast<ushort *>(errorString.data()),
1674 errorString.length());
1675 } while (errorStringLength < 0);
1676 errorString.resize(size: errorStringLength);
1677
1678 return QCoreApplication::translate(context: "QRegularExpression", key: std::move(errorString).toLatin1().constData());
1679 }
1680 return QCoreApplication::translate(context: "QRegularExpression", key: "no error");
1681}
1682
1683/*!
1684 Returns the offset, inside the pattern string, at which an error was found
1685 when checking the validity of the regular expression. If no error was
1686 found, then -1 is returned.
1687
1688 \sa pattern(), isValid(), errorString()
1689*/
1690int QRegularExpression::patternErrorOffset() const
1691{
1692 d.data()->compilePattern();
1693 return d->errorOffset;
1694}
1695
1696/*!
1697 Attempts to match the regular expression against the given \a subject
1698 string, starting at the position \a offset inside the subject, using a
1699 match of type \a matchType and honoring the given \a matchOptions.
1700
1701 The returned QRegularExpressionMatch object contains the results of the
1702 match.
1703
1704 \sa QRegularExpressionMatch, {normal matching}
1705*/
1706QRegularExpressionMatch QRegularExpression::match(const QString &subject,
1707 int offset,
1708 MatchType matchType,
1709 MatchOptions matchOptions) const
1710{
1711 d.data()->compilePattern();
1712
1713 QRegularExpressionMatchPrivate *priv = d->doMatch(subject, subjectStart: 0, subjectLength: subject.length(), offset, matchType, matchOptions);
1714 return QRegularExpressionMatch(*priv);
1715}
1716
1717/*!
1718 \since 5.5
1719 \overload
1720
1721 Attempts to match the regular expression against the given \a subjectRef
1722 string reference, starting at the position \a offset inside the subject, using a
1723 match of type \a matchType and honoring the given \a matchOptions.
1724
1725 The returned QRegularExpressionMatch object contains the results of the
1726 match.
1727
1728 \sa QRegularExpressionMatch, {normal matching}
1729*/
1730QRegularExpressionMatch QRegularExpression::match(const QStringRef &subjectRef,
1731 int offset,
1732 MatchType matchType,
1733 MatchOptions matchOptions) const
1734{
1735 d.data()->compilePattern();
1736
1737 const QString subject = subjectRef.string() ? *subjectRef.string() : QString();
1738
1739 QRegularExpressionMatchPrivate *priv = d->doMatch(subject, subjectStart: subjectRef.position(), subjectLength: subjectRef.length(), offset, matchType, matchOptions);
1740 return QRegularExpressionMatch(*priv);
1741}
1742
1743/*!
1744 \fn QRegularExpressionMatch QRegularExpression::match(QStringView subject, int offset, QRegularExpression::MatchType matchType, MatchOptions matchOptions) const
1745 \since 5.15.2
1746 \overload
1747
1748 Attempts to match the regular expression against the given \a subjectRef
1749 string reference, starting at the position \a offset inside the subject, using a
1750 match of type \a matchType and honoring the given \a matchOptions.
1751
1752 The returned QRegularExpressionMatch object contains the results of the
1753 match.
1754
1755 \note This overload has been added in 5.15.2 to simplify writing code that is portable
1756 between Qt 5.15 and Qt 6. The implementation is not tuned for performance in Qt 5.
1757
1758 \sa QRegularExpressionMatch, {normal matching}
1759*/
1760
1761/*!
1762 Attempts to perform a global match of the regular expression against the
1763 given \a subject string, starting at the position \a offset inside the
1764 subject, using a match of type \a matchType and honoring the given \a
1765 matchOptions.
1766
1767 The returned QRegularExpressionMatchIterator is positioned before the
1768 first match result (if any).
1769
1770 \sa QRegularExpressionMatchIterator, {global matching}
1771*/
1772QRegularExpressionMatchIterator QRegularExpression::globalMatch(const QString &subject,
1773 int offset,
1774 MatchType matchType,
1775 MatchOptions matchOptions) const
1776{
1777 QRegularExpressionMatchIteratorPrivate *priv =
1778 new QRegularExpressionMatchIteratorPrivate(*this,
1779 matchType,
1780 matchOptions,
1781 match(subject, offset, matchType, matchOptions));
1782
1783 return QRegularExpressionMatchIterator(*priv);
1784}
1785
1786/*!
1787 \since 5.5
1788 \overload
1789
1790 Attempts to perform a global match of the regular expression against the
1791 given \a subjectRef string reference, starting at the position \a offset inside the
1792 subject, using a match of type \a matchType and honoring the given \a
1793 matchOptions.
1794
1795 The returned QRegularExpressionMatchIterator is positioned before the
1796 first match result (if any).
1797
1798 \sa QRegularExpressionMatchIterator, {global matching}
1799*/
1800QRegularExpressionMatchIterator QRegularExpression::globalMatch(const QStringRef &subjectRef,
1801 int offset,
1802 MatchType matchType,
1803 MatchOptions matchOptions) const
1804{
1805 QRegularExpressionMatchIteratorPrivate *priv =
1806 new QRegularExpressionMatchIteratorPrivate(*this,
1807 matchType,
1808 matchOptions,
1809 match(subjectRef, offset, matchType, matchOptions));
1810
1811 return QRegularExpressionMatchIterator(*priv);
1812}
1813
1814
1815/*!
1816 \fn QRegularExpressionMatchIterator QRegularExpression::globalMatch(QStringView subject, int offset, QRegularExpression::MatchType matchType, MatchOptions matchOptions) const
1817 \since 5.15.2
1818 \overload
1819
1820 Attempts to perform a global match of the regular expression against the
1821 given \a subject string, starting at the position \a offset inside the
1822 subject, using a match of type \a matchType and honoring the given \a
1823 matchOptions.
1824
1825 The returned QRegularExpressionMatchIterator is positioned before the
1826 first match result (if any).
1827
1828 \note This overload has been added in 5.15.2 to simplify writing code that is portable
1829 between Qt 5.15 and Qt 6. The implementation is not tuned for performance in Qt 5.
1830
1831 \sa QRegularExpressionMatchIterator, {global matching}
1832*/
1833
1834/*!
1835 \since 5.4
1836
1837 Compiles the pattern immediately, including JIT compiling it (if
1838 the JIT is enabled) for optimization.
1839
1840 \sa isValid(), {Debugging Code that Uses QRegularExpression}
1841*/
1842void QRegularExpression::optimize() const
1843{
1844 d.data()->compilePattern();
1845}
1846
1847/*!
1848 Returns \c true if the regular expression is equal to \a re, or false
1849 otherwise. Two QRegularExpression objects are equal if they have
1850 the same pattern string and the same pattern options.
1851
1852 \sa operator!=()
1853*/
1854bool QRegularExpression::operator==(const QRegularExpression &re) const
1855{
1856 return (d == re.d) ||
1857 (d->pattern == re.d->pattern && d->patternOptions == re.d->patternOptions);
1858}
1859
1860/*!
1861 \fn QRegularExpression & QRegularExpression::operator=(QRegularExpression && re)
1862
1863 Move-assigns the regular expression \a re to this object, and returns a reference
1864 to the copy. Both the pattern and the pattern options are copied.
1865*/
1866
1867/*!
1868 \fn bool QRegularExpression::operator!=(const QRegularExpression &re) const
1869
1870 Returns \c true if the regular expression is different from \a re, or
1871 false otherwise.
1872
1873 \sa operator==()
1874*/
1875
1876/*!
1877 \since 5.6
1878 \relates QRegularExpression
1879
1880 Returns the hash value for \a key, using
1881 \a seed to seed the calculation.
1882*/
1883uint qHash(const QRegularExpression &key, uint seed) noexcept
1884{
1885 QtPrivate::QHashCombine hash;
1886 seed = hash(seed, key.d->pattern);
1887 seed = hash(seed, key.d->patternOptions);
1888 return seed;
1889}
1890
1891#if QT_STRINGVIEW_LEVEL < 2
1892/*!
1893 \overload
1894*/
1895QString QRegularExpression::escape(const QString &str)
1896{
1897 return escape(str: QStringView(str));
1898}
1899#endif // QT_STRINGVIEW_LEVEL < 2
1900
1901/*!
1902 \since 5.15
1903
1904 Escapes all characters of \a str so that they no longer have any special
1905 meaning when used as a regular expression pattern string, and returns
1906 the escaped string. For instance:
1907
1908 \snippet code/src_corelib_tools_qregularexpression.cpp 26
1909
1910 This is very convenient in order to build patterns from arbitrary strings:
1911
1912 \snippet code/src_corelib_tools_qregularexpression.cpp 27
1913
1914 \note This function implements Perl's quotemeta algorithm and escapes with
1915 a backslash all characters in \a str, except for the characters in the
1916 \c{[A-Z]}, \c{[a-z]} and \c{[0-9]} ranges, as well as the underscore
1917 (\c{_}) character. The only difference with Perl is that a literal NUL
1918 inside \a str is escaped with the sequence \c{"\\0"} (backslash +
1919 \c{'0'}), instead of \c{"\\\0"} (backslash + \c{NUL}).
1920*/
1921QString QRegularExpression::escape(QStringView str)
1922{
1923 QString result;
1924 const int count = str.size();
1925 result.reserve(asize: count * 2);
1926
1927 // everything but [a-zA-Z0-9_] gets escaped,
1928 // cf. perldoc -f quotemeta
1929 for (int i = 0; i < count; ++i) {
1930 const QChar current = str.at(n: i);
1931
1932 if (current == QChar::Null) {
1933 // unlike Perl, a literal NUL must be escaped with
1934 // "\\0" (backslash + 0) and not "\\\0" (backslash + NUL),
1935 // because pcre16_compile uses a NUL-terminated string
1936 result.append(c: QLatin1Char('\\'));
1937 result.append(c: QLatin1Char('0'));
1938 } else if ( (current < QLatin1Char('a') || current > QLatin1Char('z')) &&
1939 (current < QLatin1Char('A') || current > QLatin1Char('Z')) &&
1940 (current < QLatin1Char('0') || current > QLatin1Char('9')) &&
1941 current != QLatin1Char('_') )
1942 {
1943 result.append(c: QLatin1Char('\\'));
1944 result.append(c: current);
1945 if (current.isHighSurrogate() && i < (count - 1))
1946 result.append(c: str.at(n: ++i));
1947 } else {
1948 result.append(c: current);
1949 }
1950 }
1951
1952 result.squeeze();
1953 return result;
1954}
1955
1956#if QT_STRINGVIEW_LEVEL < 2
1957/*!
1958 \since 5.12
1959 \overload
1960*/
1961QString QRegularExpression::wildcardToRegularExpression(const QString &pattern)
1962{
1963 return wildcardToRegularExpression(str: QStringView(pattern));
1964}
1965#endif // QT_STRINGVIEW_LEVEL < 2
1966
1967/*!
1968 \since 5.15
1969
1970 Returns a regular expression representation of the given glob \a pattern.
1971 The transformation is targeting file path globbing, which means in particular
1972 that path separators receive special treatment. This implies that it is not
1973 just a basic translation from "*" to ".*".
1974
1975 \snippet code/src_corelib_tools_qregularexpression.cpp 31
1976
1977 The returned regular expression is already fully anchored. In other
1978 words, there is no need of calling anchoredPattern() again on the
1979 result.
1980
1981 \warning Unlike QRegExp, this implementation follows closely the definition
1982 of wildcard for glob patterns:
1983 \table
1984 \row \li \b{c}
1985 \li Any character represents itself apart from those mentioned
1986 below. Thus \b{c} matches the character \e c.
1987 \row \li \b{?}
1988 \li Matches any single character. It is the same as
1989 \b{.} in full regexps.
1990 \row \li \b{*}
1991 \li Matches zero or more of any characters. It is the
1992 same as \b{.*} in full regexps.
1993 \row \li \b{[abc]}
1994 \li Matches one character given in the bracket.
1995 \row \li \b{[a-c]}
1996 \li Matches one character from the range given in the bracket.
1997 \row \li \b{[!abc]}
1998 \li Matches one character that is not given in the bracket. It is the
1999 same as \b{[^abc]} in full regexp.
2000 \row \li \b{[!a-c]}
2001 \li Matches one character that is not from the range given in the
2002 bracket. It is the same as \b{[^a-c]} in full regexp.
2003 \endtable
2004
2005 \note The backslash (\\) character is \e not an escape char in this context.
2006 In order to match one of the special characters, place it in square brackets
2007 (for example, \c{[?]}).
2008
2009 More information about the implementation can be found in:
2010 \list
2011 \li \l {https://en.wikipedia.org/wiki/Glob_(programming)} {The Wikipedia Glob article}
2012 \li \c {man 7 glob}
2013 \endlist
2014
2015 \sa escape()
2016*/
2017QString QRegularExpression::wildcardToRegularExpression(QStringView pattern)
2018{
2019 const int wclen = pattern.length();
2020 QString rx;
2021 rx.reserve(asize: wclen + wclen / 16);
2022 int i = 0;
2023 const QChar *wc = pattern.data();
2024
2025#ifdef Q_OS_WIN
2026 const QLatin1Char nativePathSeparator('\\');
2027 const QLatin1String starEscape("[^/\\\\]*");
2028 const QLatin1String questionMarkEscape("[^/\\\\]");
2029#else
2030 const QLatin1Char nativePathSeparator('/');
2031 const QLatin1String starEscape("[^/]*");
2032 const QLatin1String questionMarkEscape("[^/]");
2033#endif
2034
2035 while (i < wclen) {
2036 const QChar c = wc[i++];
2037 switch (c.unicode()) {
2038 case '*':
2039 rx += starEscape;
2040 break;
2041 case '?':
2042 rx += questionMarkEscape;
2043 break;
2044 case '\\':
2045#ifdef Q_OS_WIN
2046 case '/':
2047 rx += QLatin1String("[/\\\\]");
2048 break;
2049#endif
2050 case '$':
2051 case '(':
2052 case ')':
2053 case '+':
2054 case '.':
2055 case '^':
2056 case '{':
2057 case '|':
2058 case '}':
2059 rx += QLatin1Char('\\');
2060 rx += c;
2061 break;
2062 case '[':
2063 rx += c;
2064 // Support for the [!abc] or [!a-c] syntax
2065 if (i < wclen) {
2066 if (wc[i] == QLatin1Char('!')) {
2067 rx += QLatin1Char('^');
2068 ++i;
2069 }
2070
2071 if (i < wclen && wc[i] == QLatin1Char(']'))
2072 rx += wc[i++];
2073
2074 while (i < wclen && wc[i] != QLatin1Char(']')) {
2075 // The '/' appearing in a character class invalidates the
2076 // regular expression parsing. It also concerns '\\' on
2077 // Windows OS types.
2078 if (wc[i] == QLatin1Char('/') || wc[i] == nativePathSeparator)
2079 return rx;
2080 if (wc[i] == QLatin1Char('\\'))
2081 rx += QLatin1Char('\\');
2082 rx += wc[i++];
2083 }
2084 }
2085 break;
2086 default:
2087 rx += c;
2088 break;
2089 }
2090 }
2091
2092 return anchoredPattern(expression: rx);
2093}
2094
2095#if QT_STRINGVIEW_LEVEL < 2
2096/*!
2097 \fn QRegularExpression::anchoredPattern(const QString &expression)
2098
2099 \since 5.12
2100
2101 \overload
2102*/
2103#endif // QT_STRINGVIEW_LEVEL < 2
2104
2105/*!
2106 \since 5.15
2107
2108 Returns the \a expression wrapped between the \c{\A} and \c{\z} anchors to
2109 be used for exact matching.
2110
2111 \sa {Porting from QRegExp's Exact Matching}
2112*/
2113QString QRegularExpression::anchoredPattern(QStringView expression)
2114{
2115 return QString()
2116 + QLatin1String("\\A(?:")
2117 + expression
2118 + QLatin1String(")\\z");
2119}
2120
2121/*!
2122 \since 5.1
2123
2124 Constructs a valid, empty QRegularExpressionMatch object. The regular
2125 expression is set to a default-constructed one; the match type to
2126 QRegularExpression::NoMatch and the match options to
2127 QRegularExpression::NoMatchOption.
2128
2129 The object will report no match through the hasMatch() and the
2130 hasPartialMatch() member functions.
2131*/
2132QRegularExpressionMatch::QRegularExpressionMatch()
2133 : d(new QRegularExpressionMatchPrivate(QRegularExpression(),
2134 QString(),
2135 0,
2136 0,
2137 QRegularExpression::NoMatch,
2138 QRegularExpression::NoMatchOption))
2139{
2140 d->isValid = true;
2141}
2142
2143/*!
2144 Destroys the match result.
2145*/
2146QRegularExpressionMatch::~QRegularExpressionMatch()
2147{
2148}
2149
2150/*!
2151 Constructs a match result by copying the result of the given \a match.
2152
2153 \sa operator=()
2154*/
2155QRegularExpressionMatch::QRegularExpressionMatch(const QRegularExpressionMatch &match)
2156 : d(match.d)
2157{
2158}
2159
2160/*!
2161 Assigns the match result \a match to this object, and returns a reference
2162 to the copy.
2163*/
2164QRegularExpressionMatch &QRegularExpressionMatch::operator=(const QRegularExpressionMatch &match)
2165{
2166 d = match.d;
2167 return *this;
2168}
2169
2170/*!
2171 \fn QRegularExpressionMatch &QRegularExpressionMatch::operator=(QRegularExpressionMatch &&match)
2172
2173 Move-assigns the match result \a match to this object, and returns a reference
2174 to the copy.
2175*/
2176
2177/*!
2178 \fn void QRegularExpressionMatch::swap(QRegularExpressionMatch &other)
2179
2180 Swaps the match result \a other with this match result. This
2181 operation is very fast and never fails.
2182*/
2183
2184/*!
2185 \internal
2186*/
2187QRegularExpressionMatch::QRegularExpressionMatch(QRegularExpressionMatchPrivate &dd)
2188 : d(&dd)
2189{
2190}
2191
2192/*!
2193 Returns the QRegularExpression object whose match() function returned this
2194 object.
2195
2196 \sa QRegularExpression::match(), matchType(), matchOptions()
2197*/
2198QRegularExpression QRegularExpressionMatch::regularExpression() const
2199{
2200 return d->regularExpression;
2201}
2202
2203
2204/*!
2205 Returns the match type that was used to get this QRegularExpressionMatch
2206 object, that is, the match type that was passed to
2207 QRegularExpression::match() or QRegularExpression::globalMatch().
2208
2209 \sa QRegularExpression::match(), regularExpression(), matchOptions()
2210*/
2211QRegularExpression::MatchType QRegularExpressionMatch::matchType() const
2212{
2213 return d->matchType;
2214}
2215
2216/*!
2217 Returns the match options that were used to get this
2218 QRegularExpressionMatch object, that is, the match options that were passed
2219 to QRegularExpression::match() or QRegularExpression::globalMatch().
2220
2221 \sa QRegularExpression::match(), regularExpression(), matchType()
2222*/
2223QRegularExpression::MatchOptions QRegularExpressionMatch::matchOptions() const
2224{
2225 return d->matchOptions;
2226}
2227
2228/*!
2229 Returns the index of the last capturing group that captured something,
2230 including the implicit capturing group 0. This can be used to extract all
2231 the substrings that were captured:
2232
2233 \snippet code/src_corelib_tools_qregularexpression.cpp 28
2234
2235 Note that some of the capturing groups with an index less than
2236 lastCapturedIndex() could have not matched, and therefore captured nothing.
2237
2238 If the regular expression did not match, this function returns -1.
2239
2240 \sa captured(), capturedStart(), capturedEnd(), capturedLength()
2241*/
2242int QRegularExpressionMatch::lastCapturedIndex() const
2243{
2244 return d->capturedCount - 1;
2245}
2246
2247/*!
2248 Returns the substring captured by the \a nth capturing group.
2249
2250 If the \a nth capturing group did not capture a string, or if there is no
2251 such capturing group, returns a null QString.
2252
2253 \note The implicit capturing group number 0 captures the substring matched
2254 by the entire pattern.
2255
2256 \sa capturedRef(), capturedView(), lastCapturedIndex(), capturedStart(), capturedEnd(),
2257 capturedLength(), QString::isNull()
2258*/
2259QString QRegularExpressionMatch::captured(int nth) const
2260{
2261 if (nth < 0 || nth > lastCapturedIndex())
2262 return QString();
2263
2264 int start = capturedStart(nth);
2265
2266 if (start == -1) // didn't capture
2267 return QString();
2268
2269 return d->subject.mid(position: start + d->subjectStart, n: capturedLength(nth));
2270}
2271
2272/*!
2273 Returns a reference to the substring captured by the \a nth capturing group.
2274
2275 If the \a nth capturing group did not capture a string, or if there is no
2276 such capturing group, returns a null QStringRef.
2277
2278 \note The implicit capturing group number 0 captures the substring matched
2279 by the entire pattern.
2280
2281 \sa captured(), capturedView(), lastCapturedIndex(), capturedStart(), capturedEnd(),
2282 capturedLength(), QStringRef::isNull()
2283*/
2284QStringRef QRegularExpressionMatch::capturedRef(int nth) const
2285{
2286 if (nth < 0 || nth > lastCapturedIndex())
2287 return QStringRef();
2288
2289 int start = capturedStart(nth);
2290
2291 if (start == -1) // didn't capture
2292 return QStringRef();
2293
2294 return d->subject.midRef(position: start + d->subjectStart, n: capturedLength(nth));
2295}
2296
2297/*!
2298 \since 5.10
2299
2300 Returns a view of the substring captured by the \a nth capturing group.
2301
2302 If the \a nth capturing group did not capture a string, or if there is no
2303 such capturing group, returns a null QStringView.
2304
2305 \note The implicit capturing group number 0 captures the substring matched
2306 by the entire pattern.
2307
2308 \sa captured(), capturedRef(), lastCapturedIndex(), capturedStart(), capturedEnd(),
2309 capturedLength(), QStringView::isNull()
2310*/
2311QStringView QRegularExpressionMatch::capturedView(int nth) const
2312{
2313 return capturedRef(nth);
2314}
2315
2316#if QT_STRINGVIEW_LEVEL < 2
2317/*!
2318 Returns the substring captured by the capturing group named \a name.
2319
2320 If the named capturing group \a name did not capture a string, or if
2321 there is no capturing group named \a name, returns a null QString.
2322
2323 \sa capturedRef(), capturedView(), capturedStart(), capturedEnd(), capturedLength(),
2324 QString::isNull()
2325*/
2326QString QRegularExpressionMatch::captured(const QString &name) const
2327{
2328 return captured(name: qToStringViewIgnoringNull(s: name));
2329}
2330
2331/*!
2332 Returns a reference to the string captured by the capturing group named \a
2333 name.
2334
2335 If the named capturing group \a name did not capture a string, or if
2336 there is no capturing group named \a name, returns a null QStringRef.
2337
2338 \sa captured(), capturedView(), capturedStart(), capturedEnd(), capturedLength(),
2339 QStringRef::isNull()
2340*/
2341QStringRef QRegularExpressionMatch::capturedRef(const QString &name) const
2342{
2343 return capturedRef(name: qToStringViewIgnoringNull(s: name));
2344}
2345#endif // QT_STRINGVIEW_LEVEL < 2
2346
2347/*!
2348 \since 5.10
2349
2350 Returns the substring captured by the capturing group named \a name.
2351
2352 If the named capturing group \a name did not capture a string, or if
2353 there is no capturing group named \a name, returns a null QString.
2354
2355 \sa capturedRef(), capturedView(), capturedStart(), capturedEnd(), capturedLength(),
2356 QString::isNull()
2357*/
2358QString QRegularExpressionMatch::captured(QStringView name) const
2359{
2360 if (name.isEmpty()) {
2361 qWarning(msg: "QRegularExpressionMatch::captured: empty capturing group name passed");
2362 return QString();
2363 }
2364 int nth = d->regularExpression.d->captureIndexForName(name);
2365 if (nth == -1)
2366 return QString();
2367 return captured(nth);
2368}
2369
2370/*!
2371 \since 5.10
2372
2373 Returns a reference to the string captured by the capturing group named \a
2374 name.
2375
2376 If the named capturing group \a name did not capture a string, or if
2377 there is no capturing group named \a name, returns a null QStringRef.
2378
2379 \sa captured(), capturedView(), capturedStart(), capturedEnd(), capturedLength(),
2380 QStringRef::isNull()
2381*/
2382QStringRef QRegularExpressionMatch::capturedRef(QStringView name) const
2383{
2384 if (name.isEmpty()) {
2385 qWarning(msg: "QRegularExpressionMatch::capturedRef: empty capturing group name passed");
2386 return QStringRef();
2387 }
2388 int nth = d->regularExpression.d->captureIndexForName(name);
2389 if (nth == -1)
2390 return QStringRef();
2391 return capturedRef(nth);
2392}
2393
2394/*!
2395 \since 5.10
2396
2397 Returns a view of the string captured by the capturing group named \a
2398 name.
2399
2400 If the named capturing group \a name did not capture a string, or if
2401 there is no capturing group named \a name, returns a null QStringView.
2402
2403 \sa captured(), capturedRef(), capturedStart(), capturedEnd(), capturedLength(),
2404 QStringRef::isNull()
2405*/
2406QStringView QRegularExpressionMatch::capturedView(QStringView name) const
2407{
2408 if (name.isEmpty()) {
2409 qWarning(msg: "QRegularExpressionMatch::capturedView: empty capturing group name passed");
2410 return QStringView();
2411 }
2412 int nth = d->regularExpression.d->captureIndexForName(name);
2413 if (nth == -1)
2414 return QStringView();
2415 return capturedView(nth);
2416}
2417
2418/*!
2419 Returns a list of all strings captured by capturing groups, in the order
2420 the groups themselves appear in the pattern string. The list includes the
2421 implicit capturing group number 0, capturing the substring matched by the
2422 entire pattern.
2423*/
2424QStringList QRegularExpressionMatch::capturedTexts() const
2425{
2426 QStringList texts;
2427 texts.reserve(alloc: d->capturedCount);
2428 for (int i = 0; i < d->capturedCount; ++i)
2429 texts << captured(nth: i);
2430 return texts;
2431}
2432
2433/*!
2434 Returns the offset inside the subject string corresponding to the
2435 starting position of the substring captured by the \a nth capturing group.
2436 If the \a nth capturing group did not capture a string or doesn't exist,
2437 returns -1.
2438
2439 \sa capturedEnd(), capturedLength(), captured()
2440*/
2441int QRegularExpressionMatch::capturedStart(int nth) const
2442{
2443 if (nth < 0 || nth > lastCapturedIndex())
2444 return -1;
2445
2446 return d->capturedOffsets.at(i: nth * 2);
2447}
2448
2449/*!
2450 Returns the length of the substring captured by the \a nth capturing group.
2451
2452 \note This function returns 0 if the \a nth capturing group did not capture
2453 a string or doesn't exist.
2454
2455 \sa capturedStart(), capturedEnd(), captured()
2456*/
2457int QRegularExpressionMatch::capturedLength(int nth) const
2458{
2459 // bound checking performed by these two functions
2460 return capturedEnd(nth) - capturedStart(nth);
2461}
2462
2463/*!
2464 Returns the offset inside the subject string immediately after the ending
2465 position of the substring captured by the \a nth capturing group. If the \a
2466 nth capturing group did not capture a string or doesn't exist, returns -1.
2467
2468 \sa capturedStart(), capturedLength(), captured()
2469*/
2470int QRegularExpressionMatch::capturedEnd(int nth) const
2471{
2472 if (nth < 0 || nth > lastCapturedIndex())
2473 return -1;
2474
2475 return d->capturedOffsets.at(i: nth * 2 + 1);
2476}
2477
2478#if QT_STRINGVIEW_LEVEL < 2
2479/*!
2480 Returns the offset inside the subject string corresponding to the starting
2481 position of the substring captured by the capturing group named \a name.
2482 If the capturing group named \a name did not capture a string or doesn't
2483 exist, returns -1.
2484
2485 \sa capturedEnd(), capturedLength(), captured()
2486*/
2487int QRegularExpressionMatch::capturedStart(const QString &name) const
2488{
2489 return capturedStart(name: qToStringViewIgnoringNull(s: name));
2490}
2491
2492/*!
2493 Returns the length of the substring captured by the capturing group named
2494 \a name.
2495
2496 \note This function returns 0 if the capturing group named \a name did not
2497 capture a string or doesn't exist.
2498
2499 \sa capturedStart(), capturedEnd(), captured()
2500*/
2501int QRegularExpressionMatch::capturedLength(const QString &name) const
2502{
2503 return capturedLength(name: qToStringViewIgnoringNull(s: name));
2504}
2505
2506/*!
2507 Returns the offset inside the subject string immediately after the ending
2508 position of the substring captured by the capturing group named \a name. If
2509 the capturing group named \a name did not capture a string or doesn't
2510 exist, returns -1.
2511
2512 \sa capturedStart(), capturedLength(), captured()
2513*/
2514int QRegularExpressionMatch::capturedEnd(const QString &name) const
2515{
2516 return capturedEnd(name: qToStringViewIgnoringNull(s: name));
2517}
2518#endif // QT_STRINGVIEW_LEVEL < 2
2519
2520/*!
2521 \since 5.10
2522
2523 Returns the offset inside the subject string corresponding to the starting
2524 position of the substring captured by the capturing group named \a name.
2525 If the capturing group named \a name did not capture a string or doesn't
2526 exist, returns -1.
2527
2528 \sa capturedEnd(), capturedLength(), captured()
2529*/
2530int QRegularExpressionMatch::capturedStart(QStringView name) const
2531{
2532 if (name.isEmpty()) {
2533 qWarning(msg: "QRegularExpressionMatch::capturedStart: empty capturing group name passed");
2534 return -1;
2535 }
2536 int nth = d->regularExpression.d->captureIndexForName(name);
2537 if (nth == -1)
2538 return -1;
2539 return capturedStart(nth);
2540}
2541
2542/*!
2543 \since 5.10
2544
2545 Returns the length of the substring captured by the capturing group named
2546 \a name.
2547
2548 \note This function returns 0 if the capturing group named \a name did not
2549 capture a string or doesn't exist.
2550
2551 \sa capturedStart(), capturedEnd(), captured()
2552*/
2553int QRegularExpressionMatch::capturedLength(QStringView name) const
2554{
2555 if (name.isEmpty()) {
2556 qWarning(msg: "QRegularExpressionMatch::capturedLength: empty capturing group name passed");
2557 return 0;
2558 }
2559 int nth = d->regularExpression.d->captureIndexForName(name);
2560 if (nth == -1)
2561 return 0;
2562 return capturedLength(nth);
2563}
2564
2565/*!
2566 \since 5.10
2567
2568 Returns the offset inside the subject string immediately after the ending
2569 position of the substring captured by the capturing group named \a name. If
2570 the capturing group named \a name did not capture a string or doesn't
2571 exist, returns -1.
2572
2573 \sa capturedStart(), capturedLength(), captured()
2574*/
2575int QRegularExpressionMatch::capturedEnd(QStringView name) const
2576{
2577 if (name.isEmpty()) {
2578 qWarning(msg: "QRegularExpressionMatch::capturedEnd: empty capturing group name passed");
2579 return -1;
2580 }
2581 int nth = d->regularExpression.d->captureIndexForName(name);
2582 if (nth == -1)
2583 return -1;
2584 return capturedEnd(nth);
2585}
2586
2587/*!
2588 Returns \c true if the regular expression matched against the subject string,
2589 or false otherwise.
2590
2591 \sa QRegularExpression::match(), hasPartialMatch()
2592*/
2593bool QRegularExpressionMatch::hasMatch() const
2594{
2595 return d->hasMatch;
2596}
2597
2598/*!
2599 Returns \c true if the regular expression partially matched against the
2600 subject string, or false otherwise.
2601
2602 \note Only a match that explicitly used the one of the partial match types
2603 can yield a partial match. Still, if such a match succeeds totally, this
2604 function will return false, while hasMatch() will return true.
2605
2606 \sa QRegularExpression::match(), QRegularExpression::MatchType, hasMatch()
2607*/
2608bool QRegularExpressionMatch::hasPartialMatch() const
2609{
2610 return d->hasPartialMatch;
2611}
2612
2613/*!
2614 Returns \c true if the match object was obtained as a result from the
2615 QRegularExpression::match() function invoked on a valid QRegularExpression
2616 object; returns \c false if the QRegularExpression was invalid.
2617
2618 \sa QRegularExpression::match(), QRegularExpression::isValid()
2619*/
2620bool QRegularExpressionMatch::isValid() const
2621{
2622 return d->isValid;
2623}
2624
2625/*!
2626 \internal
2627*/
2628QRegularExpressionMatchIterator::QRegularExpressionMatchIterator(QRegularExpressionMatchIteratorPrivate &dd)
2629 : d(&dd)
2630{
2631}
2632
2633/*!
2634 \since 5.1
2635
2636 Constructs an empty, valid QRegularExpressionMatchIterator object. The
2637 regular expression is set to a default-constructed one; the match type to
2638 QRegularExpression::NoMatch and the match options to
2639 QRegularExpression::NoMatchOption.
2640
2641 Invoking the hasNext() member function on the constructed object will
2642 return false, as the iterator is not iterating on a valid sequence of
2643 matches.
2644*/
2645QRegularExpressionMatchIterator::QRegularExpressionMatchIterator()
2646 : d(new QRegularExpressionMatchIteratorPrivate(QRegularExpression(),
2647 QRegularExpression::NoMatch,
2648 QRegularExpression::NoMatchOption,
2649 QRegularExpressionMatch()))
2650{
2651}
2652
2653/*!
2654 Destroys the QRegularExpressionMatchIterator object.
2655*/
2656QRegularExpressionMatchIterator::~QRegularExpressionMatchIterator()
2657{
2658}
2659
2660/*!
2661 Constructs a QRegularExpressionMatchIterator object as a copy of \a
2662 iterator.
2663
2664 \sa operator=()
2665*/
2666QRegularExpressionMatchIterator::QRegularExpressionMatchIterator(const QRegularExpressionMatchIterator &iterator)
2667 : d(iterator.d)
2668{
2669}
2670
2671/*!
2672 Assigns the iterator \a iterator to this object, and returns a reference to
2673 the copy.
2674*/
2675QRegularExpressionMatchIterator &QRegularExpressionMatchIterator::operator=(const QRegularExpressionMatchIterator &iterator)
2676{
2677 d = iterator.d;
2678 return *this;
2679}
2680
2681/*!
2682 \fn QRegularExpressionMatchIterator &QRegularExpressionMatchIterator::operator=(QRegularExpressionMatchIterator &&iterator)
2683
2684 Move-assigns the \a iterator to this object.
2685*/
2686
2687/*!
2688 \fn void QRegularExpressionMatchIterator::swap(QRegularExpressionMatchIterator &other)
2689
2690 Swaps the iterator \a other with this iterator object. This operation is
2691 very fast and never fails.
2692*/
2693
2694/*!
2695 Returns \c true if the iterator object was obtained as a result from the
2696 QRegularExpression::globalMatch() function invoked on a valid
2697 QRegularExpression object; returns \c false if the QRegularExpression was
2698 invalid.
2699
2700 \sa QRegularExpression::globalMatch(), QRegularExpression::isValid()
2701*/
2702bool QRegularExpressionMatchIterator::isValid() const
2703{
2704 return d->next.isValid();
2705}
2706
2707/*!
2708 Returns \c true if there is at least one match result ahead of the iterator;
2709 otherwise it returns \c false.
2710
2711 \sa next()
2712*/
2713bool QRegularExpressionMatchIterator::hasNext() const
2714{
2715 return d->hasNext();
2716}
2717
2718/*!
2719 Returns the next match result without moving the iterator.
2720
2721 \note Calling this function when the iterator is at the end of the result
2722 set leads to undefined results.
2723*/
2724QRegularExpressionMatch QRegularExpressionMatchIterator::peekNext() const
2725{
2726 if (!hasNext())
2727 qWarning(msg: "QRegularExpressionMatchIterator::peekNext() called on an iterator already at end");
2728
2729 return d->next;
2730}
2731
2732/*!
2733 Returns the next match result and advances the iterator by one position.
2734
2735 \note Calling this function when the iterator is at the end of the result
2736 set leads to undefined results.
2737*/
2738QRegularExpressionMatch QRegularExpressionMatchIterator::next()
2739{
2740 if (!hasNext()) {
2741 qWarning(msg: "QRegularExpressionMatchIterator::next() called on an iterator already at end");
2742 return d->next;
2743 }
2744
2745 QRegularExpressionMatch current = d->next;
2746 d->next = d->next.d.constData()->nextMatch();
2747 return current;
2748}
2749
2750/*!
2751 Returns the QRegularExpression object whose globalMatch() function returned
2752 this object.
2753
2754 \sa QRegularExpression::globalMatch(), matchType(), matchOptions()
2755*/
2756QRegularExpression QRegularExpressionMatchIterator::regularExpression() const
2757{
2758 return d->regularExpression;
2759}
2760
2761/*!
2762 Returns the match type that was used to get this
2763 QRegularExpressionMatchIterator object, that is, the match type that was
2764 passed to QRegularExpression::globalMatch().
2765
2766 \sa QRegularExpression::globalMatch(), regularExpression(), matchOptions()
2767*/
2768QRegularExpression::MatchType QRegularExpressionMatchIterator::matchType() const
2769{
2770 return d->matchType;
2771}
2772
2773/*!
2774 Returns the match options that were used to get this
2775 QRegularExpressionMatchIterator object, that is, the match options that
2776 were passed to QRegularExpression::globalMatch().
2777
2778 \sa QRegularExpression::globalMatch(), regularExpression(), matchType()
2779*/
2780QRegularExpression::MatchOptions QRegularExpressionMatchIterator::matchOptions() const
2781{
2782 return d->matchOptions;
2783}
2784
2785#ifndef QT_NO_DATASTREAM
2786/*!
2787 \relates QRegularExpression
2788
2789 Writes the regular expression \a re to stream \a out.
2790
2791 \sa {Serializing Qt Data Types}
2792*/
2793QDataStream &operator<<(QDataStream &out, const QRegularExpression &re)
2794{
2795 out << re.pattern() << quint32(re.patternOptions());
2796 return out;
2797}
2798
2799/*!
2800 \relates QRegularExpression
2801
2802 Reads a regular expression from stream \a in into \a re.
2803
2804 \sa {Serializing Qt Data Types}
2805*/
2806QDataStream &operator>>(QDataStream &in, QRegularExpression &re)
2807{
2808 QString pattern;
2809 quint32 patternOptions;
2810 in >> pattern >> patternOptions;
2811 re.setPattern(pattern);
2812 re.setPatternOptions(QRegularExpression::PatternOptions(patternOptions));
2813 return in;
2814}
2815#endif
2816
2817#ifndef QT_NO_DEBUG_STREAM
2818/*!
2819 \relates QRegularExpression
2820
2821 Writes the regular expression \a re into the debug object \a debug for
2822 debugging purposes.
2823
2824 \sa {Debugging Techniques}
2825*/
2826QDebug operator<<(QDebug debug, const QRegularExpression &re)
2827{
2828 QDebugStateSaver saver(debug);
2829 debug.nospace() << "QRegularExpression(" << re.pattern() << ", " << re.patternOptions() << ')';
2830 return debug;
2831}
2832
2833/*!
2834 \relates QRegularExpression
2835
2836 Writes the pattern options \a patternOptions into the debug object \a debug
2837 for debugging purposes.
2838
2839 \sa {Debugging Techniques}
2840*/
2841QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOptions)
2842{
2843 QDebugStateSaver saver(debug);
2844 QByteArray flags;
2845
2846 if (patternOptions == QRegularExpression::NoPatternOption) {
2847 flags = "NoPatternOption";
2848 } else {
2849 flags.reserve(asize: 200); // worst case...
2850 if (patternOptions & QRegularExpression::CaseInsensitiveOption)
2851 flags.append(s: "CaseInsensitiveOption|");
2852 if (patternOptions & QRegularExpression::DotMatchesEverythingOption)
2853 flags.append(s: "DotMatchesEverythingOption|");
2854 if (patternOptions & QRegularExpression::MultilineOption)
2855 flags.append(s: "MultilineOption|");
2856 if (patternOptions & QRegularExpression::ExtendedPatternSyntaxOption)
2857 flags.append(s: "ExtendedPatternSyntaxOption|");
2858 if (patternOptions & QRegularExpression::InvertedGreedinessOption)
2859 flags.append(s: "InvertedGreedinessOption|");
2860 if (patternOptions & QRegularExpression::DontCaptureOption)
2861 flags.append(s: "DontCaptureOption|");
2862 if (patternOptions & QRegularExpression::UseUnicodePropertiesOption)
2863 flags.append(s: "UseUnicodePropertiesOption|");
2864QT_WARNING_PUSH
2865QT_WARNING_DISABLE_DEPRECATED
2866 if (patternOptions & QRegularExpression::OptimizeOnFirstUsageOption)
2867 flags.append(s: "OptimizeOnFirstUsageOption|");
2868 if (patternOptions & QRegularExpression::DontAutomaticallyOptimizeOption)
2869 flags.append(s: "DontAutomaticallyOptimizeOption|");
2870QT_WARNING_POP
2871 flags.chop(n: 1);
2872 }
2873
2874 debug.nospace() << "QRegularExpression::PatternOptions(" << flags << ')';
2875
2876 return debug;
2877}
2878/*!
2879 \relates QRegularExpressionMatch
2880
2881 Writes the match object \a match into the debug object \a debug for
2882 debugging purposes.
2883
2884 \sa {Debugging Techniques}
2885*/
2886QDebug operator<<(QDebug debug, const QRegularExpressionMatch &match)
2887{
2888 QDebugStateSaver saver(debug);
2889 debug.nospace() << "QRegularExpressionMatch(";
2890
2891 if (!match.isValid()) {
2892 debug << "Invalid)";
2893 return debug;
2894 }
2895
2896 debug << "Valid";
2897
2898 if (match.hasMatch()) {
2899 debug << ", has match: ";
2900 for (int i = 0; i <= match.lastCapturedIndex(); ++i) {
2901 debug << i
2902 << ":(" << match.capturedStart(nth: i) << ", " << match.capturedEnd(nth: i)
2903 << ", " << match.captured(nth: i) << ')';
2904 if (i < match.lastCapturedIndex())
2905 debug << ", ";
2906 }
2907 } else if (match.hasPartialMatch()) {
2908 debug << ", has partial match: ("
2909 << match.capturedStart(nth: 0) << ", "
2910 << match.capturedEnd(nth: 0) << ", "
2911 << match.captured(nth: 0) << ')';
2912 } else {
2913 debug << ", no match";
2914 }
2915
2916 debug << ')';
2917
2918 return debug;
2919}
2920#endif
2921
2922// fool lupdate: make it extract those strings for translation, but don't put them
2923// inside Qt -- they're already inside libpcre (cf. man 3 pcreapi, pcre_compile.c).
2924#if 0
2925
2926/* PCRE is a library of functions to support regular expressions whose syntax
2927and semantics are as close as possible to those of the Perl 5 language.
2928
2929 Written by Philip Hazel
2930 Original API code Copyright (c) 1997-2012 University of Cambridge
2931 New API code Copyright (c) 2015 University of Cambridge
2932
2933-----------------------------------------------------------------------------
2934Redistribution and use in source and binary forms, with or without
2935modification, are permitted provided that the following conditions are met:
2936
2937 * Redistributions of source code must retain the above copyright notice,
2938 this list of conditions and the following disclaimer.
2939
2940 * Redistributions in binary form must reproduce the above copyright
2941 notice, this list of conditions and the following disclaimer in the
2942 documentation and/or other materials provided with the distribution.
2943
2944 * Neither the name of the University of Cambridge nor the names of its
2945 contributors may be used to endorse or promote products derived from
2946 this software without specific prior written permission.
2947
2948THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2949AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2950IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2951ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2952LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2953CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2954SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2955INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2956CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2957ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2958POSSIBILITY OF SUCH DAMAGE.
2959-----------------------------------------------------------------------------
2960*/
2961
2962static const char *pcreCompileErrorCodes[] =
2963{
2964 QT_TRANSLATE_NOOP("QRegularExpression", "no error"),
2965 QT_TRANSLATE_NOOP("QRegularExpression", "\\ at end of pattern"),
2966 QT_TRANSLATE_NOOP("QRegularExpression", "\\c at end of pattern"),
2967 QT_TRANSLATE_NOOP("QRegularExpression", "unrecognized character follows \\"),
2968 QT_TRANSLATE_NOOP("QRegularExpression", "numbers out of order in {} quantifier"),
2969 QT_TRANSLATE_NOOP("QRegularExpression", "number too big in {} quantifier"),
2970 QT_TRANSLATE_NOOP("QRegularExpression", "missing terminating ] for character class"),
2971 QT_TRANSLATE_NOOP("QRegularExpression", "escape sequence is invalid in character class"),
2972 QT_TRANSLATE_NOOP("QRegularExpression", "range out of order in character class"),
2973 QT_TRANSLATE_NOOP("QRegularExpression", "quantifier does not follow a repeatable item"),
2974 QT_TRANSLATE_NOOP("QRegularExpression", "internal error: unexpected repeat"),
2975 QT_TRANSLATE_NOOP("QRegularExpression", "unrecognized character after (? or (?-"),
2976 QT_TRANSLATE_NOOP("QRegularExpression", "POSIX named classes are supported only within a class"),
2977 QT_TRANSLATE_NOOP("QRegularExpression", "POSIX collating elements are not supported"),
2978 QT_TRANSLATE_NOOP("QRegularExpression", "missing closing parenthesis"),
2979 QT_TRANSLATE_NOOP("QRegularExpression", "reference to non-existent subpattern"),
2980 QT_TRANSLATE_NOOP("QRegularExpression", "pattern passed as NULL"),
2981 QT_TRANSLATE_NOOP("QRegularExpression", "unrecognised compile-time option bit(s)"),
2982 QT_TRANSLATE_NOOP("QRegularExpression", "missing ) after (?# comment"),
2983 QT_TRANSLATE_NOOP("QRegularExpression", "parentheses are too deeply nested"),
2984 QT_TRANSLATE_NOOP("QRegularExpression", "regular expression is too large"),
2985 QT_TRANSLATE_NOOP("QRegularExpression", "failed to allocate heap memory"),
2986 QT_TRANSLATE_NOOP("QRegularExpression", "unmatched closing parenthesis"),
2987 QT_TRANSLATE_NOOP("QRegularExpression", "internal error: code overflow"),
2988 QT_TRANSLATE_NOOP("QRegularExpression", "missing closing parenthesis for condition"),
2989 QT_TRANSLATE_NOOP("QRegularExpression", "lookbehind assertion is not fixed length"),
2990 QT_TRANSLATE_NOOP("QRegularExpression", "a relative value of zero is not allowed"),
2991 QT_TRANSLATE_NOOP("QRegularExpression", "conditional subpattern contains more than two branches"),
2992 QT_TRANSLATE_NOOP("QRegularExpression", "assertion expected after (?( or (?(?C)"),
2993 QT_TRANSLATE_NOOP("QRegularExpression", "digit expected after (?+ or (?-"),
2994 QT_TRANSLATE_NOOP("QRegularExpression", "unknown POSIX class name"),
2995 QT_TRANSLATE_NOOP("QRegularExpression", "internal error in pcre2_study(): should not occur"),
2996 QT_TRANSLATE_NOOP("QRegularExpression", "this version of PCRE2 does not have Unicode support"),
2997 QT_TRANSLATE_NOOP("QRegularExpression", "parentheses are too deeply nested (stack check)"),
2998 QT_TRANSLATE_NOOP("QRegularExpression", "character code point value in \\x{} or \\o{} is too large"),
2999 QT_TRANSLATE_NOOP("QRegularExpression", "lookbehind is too complicated"),
3000 QT_TRANSLATE_NOOP("QRegularExpression", "\\C is not allowed in a lookbehind assertion in UTF-" "16" " mode"),
3001 QT_TRANSLATE_NOOP("QRegularExpression", "PCRE2 does not support \\F, \\L, \\l, \\N{name}, \\U, or \\u"),
3002 QT_TRANSLATE_NOOP("QRegularExpression", "number after (?C is greater than 255"),
3003 QT_TRANSLATE_NOOP("QRegularExpression", "closing parenthesis for (?C expected"),
3004 QT_TRANSLATE_NOOP("QRegularExpression", "invalid escape sequence in (*VERB) name"),
3005 QT_TRANSLATE_NOOP("QRegularExpression", "unrecognized character after (?P"),
3006 QT_TRANSLATE_NOOP("QRegularExpression", "syntax error in subpattern name (missing terminator?)"),
3007 QT_TRANSLATE_NOOP("QRegularExpression", "two named subpatterns have the same name (PCRE2_DUPNAMES not set)"),
3008 QT_TRANSLATE_NOOP("QRegularExpression", "subpattern name must start with a non-digit"),
3009 QT_TRANSLATE_NOOP("QRegularExpression", "this version of PCRE2 does not have support for \\P, \\p, or \\X"),
3010 QT_TRANSLATE_NOOP("QRegularExpression", "malformed \\P or \\p sequence"),
3011 QT_TRANSLATE_NOOP("QRegularExpression", "unknown property name after \\P or \\p"),
3012 QT_TRANSLATE_NOOP("QRegularExpression", "subpattern name is too long (maximum " "32" " code units)"),
3013 QT_TRANSLATE_NOOP("QRegularExpression", "too many named subpatterns (maximum " "10000" ")"),
3014 QT_TRANSLATE_NOOP("QRegularExpression", "invalid range in character class"),
3015 QT_TRANSLATE_NOOP("QRegularExpression", "octal value is greater than \\377 in 8-bit non-UTF-8 mode"),
3016 QT_TRANSLATE_NOOP("QRegularExpression", "internal error: overran compiling workspace"),
3017 QT_TRANSLATE_NOOP("QRegularExpression", "internal error: previously-checked referenced subpattern not found"),
3018 QT_TRANSLATE_NOOP("QRegularExpression", "DEFINE subpattern contains more than one branch"),
3019 QT_TRANSLATE_NOOP("QRegularExpression", "missing opening brace after \\o"),
3020 QT_TRANSLATE_NOOP("QRegularExpression", "internal error: unknown newline setting"),
3021 QT_TRANSLATE_NOOP("QRegularExpression", "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number"),
3022 QT_TRANSLATE_NOOP("QRegularExpression", "(?R (recursive pattern call) must be followed by a closing parenthesis"),
3023 QT_TRANSLATE_NOOP("QRegularExpression", "obsolete error (should not occur)"),
3024 QT_TRANSLATE_NOOP("QRegularExpression", "(*VERB) not recognized or malformed"),
3025 QT_TRANSLATE_NOOP("QRegularExpression", "subpattern number is too big"),
3026 QT_TRANSLATE_NOOP("QRegularExpression", "subpattern name expected"),
3027 QT_TRANSLATE_NOOP("QRegularExpression", "internal error: parsed pattern overflow"),
3028 QT_TRANSLATE_NOOP("QRegularExpression", "non-octal character in \\o{} (closing brace missing?)"),
3029 QT_TRANSLATE_NOOP("QRegularExpression", "different names for subpatterns of the same number are not allowed"),
3030 QT_TRANSLATE_NOOP("QRegularExpression", "(*MARK) must have an argument"),
3031 QT_TRANSLATE_NOOP("QRegularExpression", "non-hex character in \\x{} (closing brace missing?)"),
3032 QT_TRANSLATE_NOOP("QRegularExpression", "\\c must be followed by a printable ASCII character"),
3033 QT_TRANSLATE_NOOP("QRegularExpression", "\\c must be followed by a letter or one of [\\]^_?"),
3034 QT_TRANSLATE_NOOP("QRegularExpression", "\\k is not followed by a braced, angle-bracketed, or quoted name"),
3035 QT_TRANSLATE_NOOP("QRegularExpression", "internal error: unknown meta code in check_lookbehinds()"),
3036 QT_TRANSLATE_NOOP("QRegularExpression", "\\N is not supported in a class"),
3037 QT_TRANSLATE_NOOP("QRegularExpression", "callout string is too long"),
3038 QT_TRANSLATE_NOOP("QRegularExpression", "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)"),
3039 QT_TRANSLATE_NOOP("QRegularExpression", "using UTF is disabled by the application"),
3040 QT_TRANSLATE_NOOP("QRegularExpression", "using UCP is disabled by the application"),
3041 QT_TRANSLATE_NOOP("QRegularExpression", "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)"),
3042 QT_TRANSLATE_NOOP("QRegularExpression", "character code point value in \\u.... sequence is too large"),
3043 QT_TRANSLATE_NOOP("QRegularExpression", "digits missing in \\x{} or \\o{} or \\N{U+}"),
3044 QT_TRANSLATE_NOOP("QRegularExpression", "syntax error or number too big in (?(VERSION condition"),
3045 QT_TRANSLATE_NOOP("QRegularExpression", "internal error: unknown opcode in auto_possessify()"),
3046 QT_TRANSLATE_NOOP("QRegularExpression", "missing terminating delimiter for callout with string argument"),
3047 QT_TRANSLATE_NOOP("QRegularExpression", "unrecognized string delimiter follows (?C"),
3048 QT_TRANSLATE_NOOP("QRegularExpression", "using \\C is disabled by the application"),
3049 QT_TRANSLATE_NOOP("QRegularExpression", "(?| and/or (?J: or (?x: parentheses are too deeply nested"),
3050 QT_TRANSLATE_NOOP("QRegularExpression", "using \\C is disabled in this PCRE2 library"),
3051 QT_TRANSLATE_NOOP("QRegularExpression", "regular expression is too complicated"),
3052 QT_TRANSLATE_NOOP("QRegularExpression", "lookbehind assertion is too long"),
3053 QT_TRANSLATE_NOOP("QRegularExpression", "pattern string is longer than the limit set by the application"),
3054 QT_TRANSLATE_NOOP("QRegularExpression", "internal error: unknown code in parsed pattern"),
3055 QT_TRANSLATE_NOOP("QRegularExpression", "internal error: bad code value in parsed_skip()"),
3056 QT_TRANSLATE_NOOP("QRegularExpression", "PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is not allowed in UTF-16 mode"),
3057 QT_TRANSLATE_NOOP("QRegularExpression", "invalid option bits with PCRE2_LITERAL"),
3058 QT_TRANSLATE_NOOP("QRegularExpression", "\\N{U+dddd} is supported only in Unicode (UTF) mode"),
3059 QT_TRANSLATE_NOOP("QRegularExpression", "invalid hyphen in option setting"),
3060 QT_TRANSLATE_NOOP("QRegularExpression", "(*alpha_assertion) not recognized"),
3061 QT_TRANSLATE_NOOP("QRegularExpression", "script runs require Unicode support, which this version of PCRE2 does not have"),
3062 QT_TRANSLATE_NOOP("QRegularExpression", "too many capturing groups (maximum 65535)"),
3063 QT_TRANSLATE_NOOP("QRegularExpression", "atomic assertion expected after (?( or (?(?C)"),
3064 QT_TRANSLATE_NOOP("QRegularExpression", "no error"),
3065 QT_TRANSLATE_NOOP("QRegularExpression", "no match"),
3066 QT_TRANSLATE_NOOP("QRegularExpression", "partial match"),
3067 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: 1 byte missing at end"),
3068 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: 2 bytes missing at end"),
3069 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: 3 bytes missing at end"),
3070 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: 4 bytes missing at end"),
3071 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: 5 bytes missing at end"),
3072 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: byte 2 top bits not 0x80"),
3073 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: byte 3 top bits not 0x80"),
3074 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: byte 4 top bits not 0x80"),
3075 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: byte 5 top bits not 0x80"),
3076 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: byte 6 top bits not 0x80"),
3077 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: 5-byte character is not allowed (RFC 3629)"),
3078 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: 6-byte character is not allowed (RFC 3629)"),
3079 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: code points greater than 0x10ffff are not defined"),
3080 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: code points 0xd800-0xdfff are not defined"),
3081 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: overlong 2-byte sequence"),
3082 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: overlong 3-byte sequence"),
3083 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: overlong 4-byte sequence"),
3084 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: overlong 5-byte sequence"),
3085 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: overlong 6-byte sequence"),
3086 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: isolated byte with 0x80 bit set"),
3087 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-8 error: illegal byte (0xfe or 0xff)"),
3088 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-16 error: missing low surrogate at end"),
3089 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-16 error: invalid low surrogate"),
3090 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-16 error: isolated low surrogate"),
3091 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-32 error: code points 0xd800-0xdfff are not defined"),
3092 QT_TRANSLATE_NOOP("QRegularExpression", "UTF-32 error: code points greater than 0x10ffff are not defined"),
3093 QT_TRANSLATE_NOOP("QRegularExpression", "bad data value"),
3094 QT_TRANSLATE_NOOP("QRegularExpression", "patterns do not all use the same character tables"),
3095 QT_TRANSLATE_NOOP("QRegularExpression", "magic number missing"),
3096 QT_TRANSLATE_NOOP("QRegularExpression", "pattern compiled in wrong mode: 8/16/32-bit error"),
3097 QT_TRANSLATE_NOOP("QRegularExpression", "bad offset value"),
3098 QT_TRANSLATE_NOOP("QRegularExpression", "bad option value"),
3099 QT_TRANSLATE_NOOP("QRegularExpression", "invalid replacement string"),
3100 QT_TRANSLATE_NOOP("QRegularExpression", "bad offset into UTF string"),
3101 QT_TRANSLATE_NOOP("QRegularExpression", "callout error code"),
3102 QT_TRANSLATE_NOOP("QRegularExpression", "invalid data in workspace for DFA restart"),
3103 QT_TRANSLATE_NOOP("QRegularExpression", "too much recursion for DFA matching"),
3104 QT_TRANSLATE_NOOP("QRegularExpression", "backreference condition or recursion test is not supported for DFA matching"),
3105 QT_TRANSLATE_NOOP("QRegularExpression", "function is not supported for DFA matching"),
3106 QT_TRANSLATE_NOOP("QRegularExpression", "pattern contains an item that is not supported for DFA matching"),
3107 QT_TRANSLATE_NOOP("QRegularExpression", "workspace size exceeded in DFA matching"),
3108 QT_TRANSLATE_NOOP("QRegularExpression", "internal error - pattern overwritten?"),
3109 QT_TRANSLATE_NOOP("QRegularExpression", "bad JIT option"),
3110 QT_TRANSLATE_NOOP("QRegularExpression", "JIT stack limit reached"),
3111 QT_TRANSLATE_NOOP("QRegularExpression", "match limit exceeded"),
3112 QT_TRANSLATE_NOOP("QRegularExpression", "no more memory"),
3113 QT_TRANSLATE_NOOP("QRegularExpression", "unknown substring"),
3114 QT_TRANSLATE_NOOP("QRegularExpression", "non-unique substring name"),
3115 QT_TRANSLATE_NOOP("QRegularExpression", "NULL argument passed"),
3116 QT_TRANSLATE_NOOP("QRegularExpression", "nested recursion at the same subject position"),
3117 QT_TRANSLATE_NOOP("QRegularExpression", "matching depth limit exceeded"),
3118 QT_TRANSLATE_NOOP("QRegularExpression", "requested value is not available"),
3119 QT_TRANSLATE_NOOP("QRegularExpression", "requested value is not set"),
3120 QT_TRANSLATE_NOOP("QRegularExpression", "offset limit set without PCRE2_USE_OFFSET_LIMIT"),
3121 QT_TRANSLATE_NOOP("QRegularExpression", "bad escape sequence in replacement string"),
3122 QT_TRANSLATE_NOOP("QRegularExpression", "expected closing curly bracket in replacement string"),
3123 QT_TRANSLATE_NOOP("QRegularExpression", "bad substitution in replacement string"),
3124 QT_TRANSLATE_NOOP("QRegularExpression", "match with end before start or start moved backwards is not supported"),
3125 QT_TRANSLATE_NOOP("QRegularExpression", "too many replacements (more than INT_MAX)"),
3126 QT_TRANSLATE_NOOP("QRegularExpression", "bad serialized data"),
3127 QT_TRANSLATE_NOOP("QRegularExpression", "heap limit exceeded"),
3128 QT_TRANSLATE_NOOP("QRegularExpression", "invalid syntax"),
3129 QT_TRANSLATE_NOOP("QRegularExpression", "internal error - duplicate substitution match"),
3130 QT_TRANSLATE_NOOP("QRegularExpression", "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching")
3131};
3132#endif // #if 0
3133
3134QT_END_NAMESPACE
3135

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