1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtTest/QtTest>
47 class tst_QRegExp : public QObject
53 void indexIn_addMoreRows(const QByteArray &stri);
55 void lastIndexIn_data();
60 void testEscapingWildcard_data();
61 void testEscapingWildcard();
62 void testInvalidWildcard_data();
63 void testInvalidWildcard();
64 void caretAnchoredOptimization();
66 void prepareEngineOptimization();
73 void rainersSlowRegExpCopyBug();
74 void nonExistingBackReferenceBug();
77 void threadsafeEngineCache();
79 void posAndCapConsistency_data();
80 void posAndCapConsistency();
82 void validityCheck_data();
86 // Testing get/set functions
87 void tst_QRegExp::getSetCheck()
90 // PatternSyntax QRegExp::patternSyntax()
91 // void QRegExp::setPatternSyntax(PatternSyntax)
92 obj1.setPatternSyntax(QRegExp::PatternSyntax(QRegExp::RegExp));
93 QCOMPARE(QRegExp::PatternSyntax(QRegExp::RegExp), obj1.patternSyntax());
94 obj1.setPatternSyntax(QRegExp::PatternSyntax(QRegExp::Wildcard));
95 QCOMPARE(QRegExp::PatternSyntax(QRegExp::Wildcard), obj1.patternSyntax());
96 obj1.setPatternSyntax(QRegExp::PatternSyntax(QRegExp::FixedString));
97 QCOMPARE(QRegExp::PatternSyntax(QRegExp::FixedString), obj1.patternSyntax());
100 extern const char email[];
102 void tst_QRegExp::lastIndexIn_data()
107 void tst_QRegExp::indexIn_data()
109 QTest::addColumn<QString>("regexpStr");
110 QTest::addColumn<QString>("target");
111 QTest::addColumn<int>("pos");
112 QTest::addColumn<int>("len");
113 QTest::addColumn<QStringList>("caps");
115 for (int i = 0; i < N; ++i) {
121 QTest::newRow( stri + "anc00" ) << QString("a(?=)z") << QString("az") << 0 << 2 << QStringList();
122 QTest::newRow( stri + "anc01" ) << QString("a(?!)z") << QString("az") << -1 << -1 << QStringList();
123 QTest::newRow( stri + "anc02" ) << QString("a(?:(?=)|(?=))z") << QString("az") << 0 << 2
125 QTest::newRow( stri + "anc03" ) << QString("a(?:(?=)|(?!))z") << QString("az") << 0 << 2
127 QTest::newRow( stri + "anc04" ) << QString("a(?:(?!)|(?=))z") << QString("az") << 0 << 2
129 QTest::newRow( stri + "anc05" ) << QString("a(?:(?!)|(?!))z") << QString("az") << -1 << -1
131 QTest::newRow( stri + "anc06" ) << QString("a(?:(?=)|b)z") << QString("az") << 0 << 2
133 QTest::newRow( stri + "anc07" ) << QString("a(?:(?=)|b)z") << QString("abz") << 0 << 3
135 QTest::newRow( stri + "anc08" ) << QString("a(?:(?!)|b)z") << QString("az") << -1 << -1
137 QTest::newRow( stri + "anc09" ) << QString("a(?:(?!)|b)z") << QString("abz") << 0 << 3
140 QTest::newRow( stri + "anc10" ) << QString("a?(?=^b$)") << QString("ab") << 0 << 1
142 QTest::newRow( stri + "anc11" ) << QString("a?(?=^b$)") << QString("b") << 0 << 0
147 QTest::newRow( stri + "bref00" ) << QString("(a*)(\\1)") << QString("aaaaa") << 0 << 4
148 << QStringList( QStringList() << "aa" << "aa" );
149 QTest::newRow( stri + "bref01" ) << QString("<(\\w*)>.+</\\1>") << QString("<b>blabla</b>bla</>")
150 << 0 << 13 << QStringList( QStringList() << "b" );
151 QTest::newRow( stri + "bref02" ) << QString("<(\\w*)>.+</\\1>") << QString("<>blabla</b>bla</>")
152 << 0 << 18 << QStringList( QStringList() << "" );
153 QTest::newRow( stri + "bref03" ) << QString("((a*\\2)\\2)") << QString("aaaa") << 0 << 4
154 << QStringList( QStringList() << QString("aaaa") << "aa" );
155 QTest::newRow( stri + "bref04" ) << QString("^(aa+)\\1+$") << QString("aaaaaa") << 0 << 6
156 << QStringList( QStringList() << QString("aa") );
157 QTest::newRow( stri + "bref05" ) << QString("^(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(14)"
158 "\\14\\13\\12\\11\\10\\9\\8\\7\\6\\5\\4\\3\\2\\1")
159 << QString("12345678910111213141413121110987654321") << 0 << 38
160 << QStringList( QStringList() << "1" << "2" << "3" << "4" << "5" << "6"
161 << "7" << "8" << "9" << "10" << "11"
162 << "12" << "13" << "14");
165 QTest::newRow( stri + "cap00" ) << QString("(a*)") << QString("") << 0 << 0
166 << QStringList( QStringList() << QString("") );
167 QTest::newRow( stri + "cap01" ) << QString("(a*)") << QString("aaa") << 0 << 3
168 << QStringList( QStringList() << "aaa" );
169 QTest::newRow( stri + "cap02" ) << QString("(a*)") << QString("baaa") << 0 << 0
170 << QStringList( QStringList() << QString("") );
171 QTest::newRow( stri + "cap03" ) << QString("(a*)(a*)") << QString("aaa") << 0 << 3
172 << QStringList( QStringList() << QString("aaa") << QString("") );
173 QTest::newRow( stri + "cap04" ) << QString("(a*)(b*)") << QString("aaabbb") << 0 << 6
174 << QStringList( QStringList() << QString("aaa") << QString("bbb") );
175 QTest::newRow( stri + "cap06" ) << QString("(a*)a*") << QString("aaa") << 0 << 3
176 << QStringList( QStringList() << QString("aaa") );
177 QTest::newRow( stri + "cap07" ) << QString("((a*a*)*)") << QString("aaa") << 0 << 3
178 << QStringList( QStringList() << "aaa" << QString("aaa") );
179 QTest::newRow( stri + "cap08" ) << QString("(((a)*(b)*)*)") << QString("ababa") << 0 << 5
180 << QStringList( QStringList() << QString("ababa") << QString("a") << QString("a")
182 QTest::newRow( stri + "cap09" ) << QString("(((a)*(b)*)c)*") << QString("") << 0 << 0
183 << QStringList( QStringList() << QString("") << QString("") << QString("") << QString("") );
184 QTest::newRow( stri + "cap10" ) << QString("(((a)*(b)*)c)*") << QString("abc") << 0 << 3
185 << QStringList( QStringList() << "abc" << "ab" << "a"
187 QTest::newRow( stri + "cap11" ) << QString("(((a)*(b)*)c)*") << QString("abcc") << 0 << 4
188 << QStringList( QStringList() << "c" << "" << "" << "" );
189 QTest::newRow( stri + "cap12" ) << QString("(((a)*(b)*)c)*") << QString("abcac") << 0 << 5
190 << QStringList( QStringList() << "ac" << "a" << "a" << "" );
191 QTest::newRow( stri + "cap13" ) << QString("(to|top)?(o|polo)?(gical|o?logical)")
192 << QString("topological") << 0 << 11
193 << QStringList( QStringList() << "top" << "o"
195 QTest::newRow( stri + "cap14" ) << QString("(a)+") << QString("aaaa") << 0 << 4
196 << QStringList( QStringList() << "a" );
199 QTest::newRow( stri + "cat00" ) << QString("") << QString("") << 0 << 0 << QStringList();
200 QTest::newRow( stri + "cat01" ) << QString("") << QString("a") << 0 << 0 << QStringList();
201 QTest::newRow( stri + "cat02" ) << QString("a") << QString("") << -1 << -1 << QStringList();
202 QTest::newRow( stri + "cat03" ) << QString("a") << QString("a") << 0 << 1 << QStringList();
203 QTest::newRow( stri + "cat04" ) << QString("a") << QString("b") << -1 << -1 << QStringList();
204 QTest::newRow( stri + "cat05" ) << QString("b") << QString("a") << -1 << -1 << QStringList();
205 QTest::newRow( stri + "cat06" ) << QString("ab") << QString("ab") << 0 << 2 << QStringList();
206 QTest::newRow( stri + "cat07" ) << QString("ab") << QString("ba") << -1 << -1 << QStringList();
207 QTest::newRow( stri + "cat08" ) << QString("abab") << QString("abbaababab") << 4 << 4 << QStringList();
209 indexIn_addMoreRows(stri);
213 void tst_QRegExp::indexIn_addMoreRows(const QByteArray &stri)
215 // from Perl Cookbook
216 QTest::newRow( stri + "cook00" ) << QString("^(m*)(d?c{0,3}|c[dm])(1?x{0,3}|x[lc])(v?i{0,3}|i[vx])$")
217 << QString("mmxl") << 0 << 4
218 << QStringList( QStringList() << "mm" << "" << "xl"
220 QTest::newRow( stri + "cook01" ) << QString("(\\S+)(\\s+)(\\S+)") << QString(" a b") << 1 << 5
221 << QStringList( QStringList() << "a" << " " << "b" );
222 QTest::newRow( stri + "cook02" ) << QString("(\\w+)\\s*=\\s*(.*)\\s*$") << QString(" PATH=. ") << 1
223 << 7 << QStringList( QStringList() << "PATH" << ". " );
224 QTest::newRow( stri + "cook03" ) << QString(".{80,}")
225 << QString("0000000011111111222222223333333344444444555"
226 "5555566666666777777778888888899999999000000"
228 << 0 << 96 << QStringList();
229 QTest::newRow( stri + "cook04" ) << QString("(\\d+)/(\\d+)/(\\d+) (\\d+):(\\d+):(\\d+)")
230 << QString("1978/05/24 07:30:00") << 0 << 19
231 << QStringList( QStringList() << "1978" << "05" << "24"
232 << "07" << "30" << "00" );
233 QTest::newRow( stri + "cook05" ) << QString("/usr/bin") << QString("/usr/local/bin:/usr/bin")
234 << 15 << 8 << QStringList();
235 QTest::newRow( stri + "cook06" ) << QString("%([0-9A-Fa-f]{2})") << QString("http://%7f") << 7 << 3
236 << QStringList( QStringList() << "7f" );
237 QTest::newRow( stri + "cook07" ) << QString("/\\*.*\\*/") << QString("i++; /* increment i */") << 5
238 << 17 << QStringList();
239 QTest::newRow( stri + "cook08" ) << QString("^\\s+") << QString(" aaa ") << 0 << 3
241 QTest::newRow( stri + "cook09" ) << QString("\\s+$") << QString(" aaa ") << 6 << 3
243 QTest::newRow( stri + "cook10" ) << QString("^.*::") << QString("Box::cat") << 0 << 5
245 QTest::newRow( stri + "cook11" ) << QString("^([01]?\\d\\d|2[0-4]\\d|25[0-5])\\.([01]?\\"
246 "d\\d|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d|2[0-"
247 "4]\\d|25[0-5])\\.([01]?\\d\\d|2[0-4]\\d|25["
249 << QString("255.00.40.30") << 0 << 12
250 << QStringList( QStringList() << "255" << "00" << "40"
252 QTest::newRow( stri + "cook12" ) << QString("^.*/") << QString(" /usr/local/bin/moc") << 0 << 16
254 QTest::newRow( stri + "cook13" ) << QString(":co#(\\d+):") << QString("bla:co#55:") << 3 << 7
255 << QStringList( QStringList() << "55" );
256 QTest::newRow( stri + "cook14" ) << QString("linux") << QString("alphalinuxinunix") << 5 << 5
258 QTest::newRow( stri + "cook15" ) << QString("(\\d+\\.?\\d*|\\.\\d+)") << QString("0.0.5") << 0 << 3
259 << QStringList( QStringList() << "0.0" );
261 // mathematical trivia
262 QTest::newRow( stri + "math00" ) << QString("^(a\\1*)$") << QString("a") << 0 << 1
263 << QStringList( QStringList() << "a" );
264 QTest::newRow( stri + "math01" ) << QString("^(a\\1*)$") << QString("aa") << 0 << 2
265 << QStringList( QStringList() << "aa" );
266 QTest::newRow( stri + "math02" ) << QString("^(a\\1*)$") << QString("aaa") << -1 << -1
267 << QStringList( QStringList() << QString() );
268 QTest::newRow( stri + "math03" ) << QString("^(a\\1*)$") << QString("aaaa") << 0 << 4
269 << QStringList( QStringList() << "aaaa" );
270 QTest::newRow( stri + "math04" ) << QString("^(a\\1*)$") << QString("aaaaa") << -1 << -1
271 << QStringList( QStringList() << QString() );
272 QTest::newRow( stri + "math05" ) << QString("^(a\\1*)$") << QString("aaaaaa") << -1 << -1
273 << QStringList( QStringList() << QString() );
274 QTest::newRow( stri + "math06" ) << QString("^(a\\1*)$") << QString("aaaaaaa") << -1 << -1
275 << QStringList( QStringList() << QString() );
276 QTest::newRow( stri + "math07" ) << QString("^(a\\1*)$") << QString("aaaaaaaa") << 0 << 8
277 << QStringList( QStringList() << "aaaaaaaa" );
278 QTest::newRow( stri + "math08" ) << QString("^(a\\1*)$") << QString("aaaaaaaaa") << -1 << -1
279 << QStringList( QStringList() << QString() );
280 QTest::newRow( stri + "math09" ) << QString("^a(?:a(\\1a))*$") << QString("a") << 0 << 1
281 << QStringList( QStringList() << "" );
282 QTest::newRow( stri + "math10" ) << QString("^a(?:a(\\1a))*$") << QString("aaa") << 0 << 3
283 << QStringList( QStringList() << "a" );
285 QTest::newRow( stri + "math13" ) << QString("^(?:((?:^a)?\\2\\3)(\\3\\1|(?=a$))(\\1\\2|("
287 << QString("aaa") << 0 << 3
288 << QStringList( QStringList() << "a" << "a" << "" );
289 QTest::newRow( stri + "math14" ) << QString("^(?:((?:^a)?\\2\\3)(\\3\\1|(?=a$))(\\1\\2|("
291 << QString("aaaaa") << 0 << 5
292 << QStringList( QStringList() << "a" << "a" << "aa" );
293 QTest::newRow( stri + "math17" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
294 ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
295 << QString("aaa") << 0 << 3
296 << QStringList( QStringList() << "" << "" << "" << "aaa" << "a" << "aa" );
297 QTest::newRow( stri + "math18" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
298 ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
299 << QString("aaaaa") << 0 << 5
300 << QStringList( QStringList() << "aaaaa" << "a" << "aaa" << "" << "" << "" );
301 QTest::newRow( stri + "math19" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
302 ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
303 << QString("aaaaaaaa") << 0 << 8
304 << QStringList( QStringList() << "" << "" << "" << "aaaaaaaa" << "a" << "aa" );
305 QTest::newRow( stri + "math20" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
306 ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
307 << QString("aaaaaaaaa") << -1 << -1
308 << QStringList( QStringList() << QString()
314 QTest::newRow( stri + "math21" ) << QString("^(aa+)\\1+$") << QString("aaaaaaaaaaaa") << 0 << 12
315 << QStringList( QStringList() << "aa" );
317 static const char * const squareRegExp[] = {
320 "^((\\2a)*)\\1\\2a$",
326 while ( squareRegExp[ii] != 0 ) {
327 for ( int j = 0; j < 100; j++ ) {
329 name.sprintf( "square%.1d%.2d", ii, j );
332 target.fill( 'a', j );
337 for ( int k = 1; k * k <= j; k++ ) {
345 QTest::newRow( name.toLatin1() ) << QString( squareRegExp[ii] ) << target
346 << pos << len << QStringList( "IGNORE ME" );
352 QTest::newRow( stri + "misc00" ) << QString(email)
353 << QString("email123@example.com") << 0 << 20
355 QTest::newRow( stri + "misc01" ) << QString("[0-9]*\\.[0-9]+") << QString("pi = 3.14") << 5 << 4
359 QTest::newRow( stri + "or00" ) << QString("(?:|b)") << QString("xxx") << 0 << 0 << QStringList();
360 QTest::newRow( stri + "or01" ) << QString("(?:|b)") << QString("b") << 0 << 1 << QStringList();
361 QTest::newRow( stri + "or02" ) << QString("(?:b|)") << QString("") << 0 << 0 << QStringList();
362 QTest::newRow( stri + "or03" ) << QString("(?:b|)") << QString("b") << 0 << 1 << QStringList();
363 QTest::newRow( stri + "or04" ) << QString("(?:||b||)") << QString("") << 0 << 0 << QStringList();
364 QTest::newRow( stri + "or05" ) << QString("(?:||b||)") << QString("b") << 0 << 1 << QStringList();
365 QTest::newRow( stri + "or06" ) << QString("(?:a|b)") << QString("") << -1 << -1 << QStringList();
366 QTest::newRow( stri + "or07" ) << QString("(?:a|b)") << QString("cc") << -1 << -1 << QStringList();
367 QTest::newRow( stri + "or08" ) << QString("(?:a|b)") << QString("abc") << 0 << 1 << QStringList();
368 QTest::newRow( stri + "or09" ) << QString("(?:a|b)") << QString("cba") << 1 << 1 << QStringList();
369 QTest::newRow( stri + "or10" ) << QString("(?:ab|ba)") << QString("aba") << 0 << 2
371 QTest::newRow( stri + "or11" ) << QString("(?:ab|ba)") << QString("bab") << 0 << 2
373 QTest::newRow( stri + "or12" ) << QString("(?:ab|ba)") << QString("caba") << 1 << 2
375 QTest::newRow( stri + "or13" ) << QString("(?:ab|ba)") << QString("cbab") << 1 << 2
379 QTest::newRow( stri + "qua00" ) << QString("((([a-j])){0,0})") << QString("") << 0 << 0
380 << QStringList( QStringList() << "" << "" << "" );
381 QTest::newRow( stri + "qua01" ) << QString("((([a-j])){0,0})") << QString("a") << 0 << 0
382 << QStringList( QStringList() << "" << "" << "" );
383 QTest::newRow( stri + "qua02" ) << QString("((([a-j])){0,0})") << QString("xyz") << 0 << 0
384 << QStringList( QStringList() << "" << "" << "" );
385 QTest::newRow( stri + "qua03" ) << QString("((([a-j]))?)") << QString("") << 0 << 0
386 << QStringList( QStringList() << "" << "" << "" );
387 QTest::newRow( stri + "qua04" ) << QString("((([a-j]))?)") << QString("a") << 0 << 1
388 << QStringList( QStringList() << "a" << "a" << "a" );
389 QTest::newRow( stri + "qua05" ) << QString("((([a-j]))?)") << QString("x") << 0 << 0
390 << QStringList( QStringList() << "" << "" << "" );
391 QTest::newRow( stri + "qua06" ) << QString("((([a-j]))?)") << QString("ab") << 0 << 1
392 << QStringList( QStringList() << "a" << "a" << "a" );
393 QTest::newRow( stri + "qua07" ) << QString("((([a-j]))?)") << QString("xa") << 0 << 0
394 << QStringList( QStringList() << "" << "" << "" );
395 QTest::newRow( stri + "qua08" ) << QString("((([a-j])){0,3})") << QString("") << 0 << 0
396 << QStringList( QStringList() << "" << "" << "" );
397 QTest::newRow( stri + "qua09" ) << QString("((([a-j])){0,3})") << QString("a") << 0 << 1
398 << QStringList( QStringList() << "a" << "a" << "a" );
399 QTest::newRow( stri + "qua10" ) << QString("((([a-j])){0,3})") << QString("abcd") << 0 << 3
400 << QStringList( QStringList() << "abc" << "c" << "c" );
401 QTest::newRow( stri + "qua11" ) << QString("((([a-j])){0,3})") << QString("abcde") << 0 << 3
402 << QStringList( QStringList() << "abc" << "c" << "c" );
403 QTest::newRow( stri + "qua12" ) << QString("((([a-j])){2,4})") << QString("a") << -1 << -1
404 << QStringList( QStringList() << QString()
407 QTest::newRow( stri + "qua13" ) << QString("((([a-j])){2,4})") << QString("ab") << 0 << 2
408 << QStringList( QStringList() << "ab" << "b" << "b" );
409 QTest::newRow( stri + "qua14" ) << QString("((([a-j])){2,4})") << QString("abcd") << 0 << 4
410 << QStringList( QStringList() << "abcd" << "d" << "d" );
411 QTest::newRow( stri + "qua15" ) << QString("((([a-j])){2,4})") << QString("abcdef") << 0 << 4
412 << QStringList( QStringList() << "abcd" << "d" << "d" );
413 QTest::newRow( stri + "qua16" ) << QString("((([a-j])){2,4})") << QString("xaybcd") << 3 << 3
414 << QStringList( QStringList() << "bcd" << "d" << "d" );
415 QTest::newRow( stri + "qua17" ) << QString("((([a-j])){0,})") << QString("abcdefgh") << 0 << 8
416 << QStringList( QStringList() << "abcdefgh" << "h" << "h" );
417 QTest::newRow( stri + "qua18" ) << QString("((([a-j])){,0})") << QString("abcdefgh") << 0 << 0
418 << QStringList( QStringList() << "" << "" << "" );
419 QTest::newRow( stri + "qua19" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("123332333") << 0
421 << QStringList( QStringList() << "123332333" << "2333"
423 QTest::newRow( stri + "qua20" ) << QString("(1(2(3){3,4}){2,3}){1,2}")
424 << QString("12333323333233331233332333323333") << 0 << 32
425 << QStringList( QStringList() << "1233332333323333"
427 QTest::newRow( stri + "qua21" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("") << -1 << -1
428 << QStringList( QStringList() << QString()
431 QTest::newRow( stri + "qua22" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("12333") << -1
433 << QStringList( QStringList() << QString()
436 QTest::newRow( stri + "qua23" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("12333233") << -1
438 << QStringList( QStringList() << QString()
441 QTest::newRow( stri + "qua24" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("122333") << -1
443 << QStringList( QStringList() << QString()
448 QTest::newRow( stri + "star00" ) << QString("(?:)*") << QString("") << 0 << 0 << QStringList();
449 QTest::newRow( stri + "star01" ) << QString("(?:)*") << QString("abc") << 0 << 0 << QStringList();
450 QTest::newRow( stri + "star02" ) << QString("(?:a)*") << QString("") << 0 << 0 << QStringList();
451 QTest::newRow( stri + "star03" ) << QString("(?:a)*") << QString("a") << 0 << 1 << QStringList();
452 QTest::newRow( stri + "star04" ) << QString("(?:a)*") << QString("aaa") << 0 << 3 << QStringList();
453 QTest::newRow( stri + "star05" ) << QString("(?:a)*") << QString("bbbbaaa") << 0 << 0
455 QTest::newRow( stri + "star06" ) << QString("(?:a)*") << QString("bbbbaaabbaaaaa") << 0 << 0
457 QTest::newRow( stri + "star07" ) << QString("(?:b)*(?:a)*") << QString("") << 0 << 0
459 QTest::newRow( stri + "star08" ) << QString("(?:b)*(?:a)*") << QString("a") << 0 << 1
461 QTest::newRow( stri + "star09" ) << QString("(?:b)*(?:a)*") << QString("aaa") << 0 << 3
463 QTest::newRow( stri + "star10" ) << QString("(?:b)*(?:a)*") << QString("bbbbaaa") << 0 << 7
465 QTest::newRow( stri + "star11" ) << QString("(?:b)*(?:a)*") << QString("bbbbaaabbaaaaa") << 0 << 7
467 QTest::newRow( stri + "star12" ) << QString("(?:a|b)*") << QString("c") << 0 << 0 << QStringList();
468 QTest::newRow( stri + "star13" ) << QString("(?:a|b)*") << QString("abac") << 0 << 3
470 QTest::newRow( stri + "star14" ) << QString("(?:a|b|)*") << QString("c") << 0 << 0
472 QTest::newRow( stri + "star15" ) << QString("(?:a|b|)*") << QString("abac") << 0 << 3
474 QTest::newRow( stri + "star16" ) << QString("(?:ab|ba|b)*") << QString("abbbababbbaaab") << 0 << 11
478 void tst_QRegExp::exactMatch()
480 QRegExp rx_d( "\\d" );
481 QRegExp rx_s( "\\s" );
482 QRegExp rx_w( "\\w" );
483 QRegExp rx_D( "\\D" );
484 QRegExp rx_S( "\\S" );
485 QRegExp rx_W( "\\W" );
487 for ( int i = 0; i < 65536; i++ ) {
489 bool is_d = ( ch.category() == QChar::Number_DecimalDigit );
490 bool is_s = ch.isSpace();
491 bool is_w = ( ch.isLetterOrNumber()
495 QVERIFY( rx_d.exactMatch(QString(ch)) == is_d );
496 QVERIFY( rx_s.exactMatch(QString(ch)) == is_s );
497 QVERIFY( rx_w.exactMatch(QString(ch)) == is_w );
498 QVERIFY( rx_D.exactMatch(QString(ch)) != is_d );
499 QVERIFY( rx_S.exactMatch(QString(ch)) != is_s );
500 QVERIFY( rx_W.exactMatch(QString(ch)) != is_w );
504 void tst_QRegExp::capturedTexts()
506 QRegExp rx1("a*(a*)", Qt::CaseSensitive, QRegExp::RegExp);
507 rx1.exactMatch("aaa");
508 QCOMPARE(rx1.matchedLength(), 3);
509 QCOMPARE(rx1.cap(0), QString("aaa"));
510 QCOMPARE(rx1.cap(1), QString("aaa"));
512 QRegExp rx2("a*(a*)", Qt::CaseSensitive, QRegExp::RegExp2);
513 rx2.exactMatch("aaa");
514 QCOMPARE(rx2.matchedLength(), 3);
515 QCOMPARE(rx2.cap(0), QString("aaa"));
516 QCOMPARE(rx2.cap(1), QString(""));
518 QRegExp rx3("(?:a|aa)(a*)", Qt::CaseSensitive, QRegExp::RegExp);
519 rx3.exactMatch("aaa");
520 QCOMPARE(rx3.matchedLength(), 3);
521 QCOMPARE(rx3.cap(0), QString("aaa"));
522 QCOMPARE(rx3.cap(1), QString("aa"));
524 QRegExp rx4("(?:a|aa)(a*)", Qt::CaseSensitive, QRegExp::RegExp2);
525 rx4.exactMatch("aaa");
526 QCOMPARE(rx4.matchedLength(), 3);
527 QCOMPARE(rx4.cap(0), QString("aaa"));
528 QCOMPARE(rx4.cap(1), QString("a"));
530 QRegExp rx5("(a)*(a*)", Qt::CaseSensitive, QRegExp::RegExp);
531 rx5.exactMatch("aaa");
532 QCOMPARE(rx5.matchedLength(), 3);
533 QCOMPARE(rx5.cap(0), QString("aaa"));
534 QCOMPARE(rx5.cap(1), QString("a"));
535 QCOMPARE(rx5.cap(2), QString("aa"));
537 QRegExp rx6("(a)*(a*)", Qt::CaseSensitive, QRegExp::RegExp2);
538 rx6.exactMatch("aaa");
539 QCOMPARE(rx6.matchedLength(), 3);
540 QCOMPARE(rx6.cap(0), QString("aaa"));
541 QCOMPARE(rx6.cap(1), QString("a"));
542 QCOMPARE(rx6.cap(2), QString(""));
544 QRegExp rx7("([A-Za-z_])([A-Za-z_0-9]*)");
545 rx7.setCaseSensitivity(Qt::CaseSensitive);
546 rx7.setPatternSyntax(QRegExp::RegExp);
547 QCOMPARE(rx7.captureCount(), 2);
549 int pos = rx7.indexIn("(10 + delta4) * 32");
551 QCOMPARE(rx7.matchedLength(), 6);
552 QCOMPARE(rx7.cap(0), QString("delta4"));
553 QCOMPARE(rx7.cap(1), QString("d"));
554 QCOMPARE(rx7.cap(2), QString("elta4"));
557 void tst_QRegExp::indexIn()
559 QFETCH( QString, regexpStr );
560 QFETCH( QString, target );
563 QFETCH( QStringList, caps );
565 caps.prepend( "dummy cap(0)" );
568 QRegExp rx( regexpStr );
569 QVERIFY( rx.isValid() );
571 int mypos = rx.indexIn( target );
572 int mylen = rx.matchedLength();
573 QStringList mycaps = rx.capturedTexts();
575 QCOMPARE( mypos, pos );
576 QCOMPARE( mylen, len );
577 if ( caps.size() > 1 && caps[1] != "IGNORE ME" ) {
578 QCOMPARE( mycaps.count(), caps.count() );
579 for ( int i = 1; i < (int) mycaps.count(); i++ )
580 QCOMPARE( mycaps[i], caps[i] );
584 // same as above, but with RegExp2
586 QRegExp rx( regexpStr, Qt::CaseSensitive, QRegExp::RegExp2 );
587 QVERIFY( rx.isValid() );
589 int mypos = rx.indexIn( target );
590 int mylen = rx.matchedLength();
591 QStringList mycaps = rx.capturedTexts();
593 QCOMPARE( mypos, pos );
594 QCOMPARE( mylen, len );
595 if ( caps.size() > 1 && caps[1] != "IGNORE ME" ) {
596 QCOMPARE( mycaps.count(), caps.count() );
597 for ( int i = 1; i < (int) mycaps.count(); i++ )
598 QCOMPARE( mycaps[i], caps[i] );
603 void tst_QRegExp::lastIndexIn()
605 QFETCH( QString, regexpStr );
606 QFETCH( QString, target );
609 QFETCH( QStringList, caps );
611 caps.prepend( "dummy" );
614 The test data was really designed for indexIn(), not
615 lastIndexIn(), but it turns out that we can reuse much of that
620 QRegExp rx( regexpStr );
621 QVERIFY( rx.isValid() );
623 int mypos = rx.lastIndexIn( target, target.length() );
624 int mylen = rx.matchedLength();
625 QStringList mycaps = rx.capturedTexts();
627 if ( mypos <= pos || pos == -1 ) {
628 QCOMPARE( mypos, pos );
629 QCOMPARE( mylen, len );
631 if (caps.size() > 1 && caps[1] != "IGNORE ME") {
632 QCOMPARE( mycaps.count(), caps.count() );
633 for ( int i = 1; i < (int) mycaps.count(); i++ )
634 QCOMPARE( mycaps[i], caps[i] );
640 QRegExp rx( regexpStr, Qt::CaseSensitive, QRegExp::RegExp2 );
641 QVERIFY( rx.isValid() );
643 int mypos = rx.lastIndexIn( target, target.length() );
644 int mylen = rx.matchedLength();
645 QStringList mycaps = rx.capturedTexts();
647 if ( mypos <= pos || pos == -1 ) {
648 QCOMPARE( mypos, pos );
649 QCOMPARE( mylen, len );
651 if (caps.size() > 1 && caps[1] != "IGNORE ME") {
652 QCOMPARE( mycaps.count(), caps.count() );
653 for ( int i = 1; i < (int) mycaps.count(); i++ )
654 QCOMPARE( mycaps[i], caps[i] );
660 void tst_QRegExp::matchedLength()
663 r1.exactMatch( "aaaba" );
664 QCOMPARE( r1.matchedLength(), 3 );
668 "^[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff"
669 "]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\x"
670 "ff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:"
671 "(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@"
672 ",;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\""
673 "]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?"
674 ":\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x"
675 "80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*"
676 ")*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*"
677 "(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\"
678 "\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015("
679 ")]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>"
680 "@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\["
681 "\\]\\000-\\037\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\"
682 "x80-\\xff][^\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?:\\([^\\\\\\x"
683 "80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\"
684 "015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\"
685 "\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*@[\\040\\t]*(?:\\([^\\\\\\x"
686 "80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\"
687 "015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\"
688 "\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\["
689 "\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037"
690 "\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff"
691 "])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80"
692 "-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x"
693 "80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]"
694 "*)*(?:\\.[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x"
695 "80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\"
696 "\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040"
697 "\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\"
698 "040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xf"
699 "f\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-"
700 "\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015"
701 "()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x8"
702 "0-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*|(?:[^(\\040)<>@,;:\".\\\\\\[\\"
703 "]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x"
704 "80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\x80-\\xff][^\\\\"
705 "\\x80-\\xff\\n\\015\"]*)*\")[^()<>@,;:\".\\\\\\[\\]\\x80-\\xff\\000-\\"
706 "010\\012-\\037]*(?:(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x8"
707 "0-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\"
708 "x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)|\"[^\\\\"
709 "\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015"
710 "\"]*)*\")[^()<>@,;:\".\\\\\\[\\]\\x80-\\xff\\000-\\010\\012-\\037]*)*<"
711 "[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]"
712 "|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xf"
713 "f\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:@"
714 "[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]"
715 "|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xf"
716 "f\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:["
717 "^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:"
718 "\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015"
719 "\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n"
720 "\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:"
721 "\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff"
722 "\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*(?:\\([^\\\\\\x80-\\xff"
723 "\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*("
724 "?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\x"
725 "ff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-"
726 "\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xf"
727 "f])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\"
728 "040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\"
729 "([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\"
730 "n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*(?:,["
731 "\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|"
732 "\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff"
733 "\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*@[\\0"
734 "40\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\("
735 "[^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n"
736 "\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\"
737 "040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\"
738 "\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]"
739 "]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()"
740 "]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\"
741 "x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015"
742 "()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015"
743 "()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^"
744 "\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\0"
745 "15()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x8"
746 "0-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?"
747 ":[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*("
748 "?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\"
749 "x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]"
750 "*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*)*:[\\040\\t]*"
751 "(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\"
752 "\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015("
753 ")]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)?(?:[^(\\040)"
754 "<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\"
755 "[\\]\\000-\\037\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^"
756 "\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?:\\([^\\\\"
757 "\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\"
758 "n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\"
759 "\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*(?:\\([^\\"
760 "\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff"
761 "\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^"
762 "\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\"
763 "\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\0"
764 "37\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\x80-\\xff][^"
765 "\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n"
766 "\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:"
767 "\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff"
768 "\\n\\015()]*)*\\)[\\040\\t]*)*)*@[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n"
769 "\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:"
770 "\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff"
771 "\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\0"
772 "37\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])"
773 "|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040"
774 "\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^"
775 "\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\"
776 "015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\0"
777 "40\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\("
778 "[^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n"
779 "\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\"
780 "040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\"
781 "\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]"
782 "]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()"
783 "]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\"
784 "x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015"
785 "()]*)*\\)[\\040\\t]*)*)*>)$";
787 void tst_QRegExp::wildcard_data()
789 QTest::addColumn<QString>("rxp");
790 QTest::addColumn<QString>("string");
791 QTest::addColumn<int>("foundIndex");
793 QTest::newRow( "data0" ) << QString("*.html") << QString("test.html") << 0;
794 QTest::newRow( "data1" ) << QString("*.html") << QString("test.htm") << -1;
795 QTest::newRow( "data2" ) << QString("bar*") << QString("foobarbaz") << 3;
796 QTest::newRow( "data3" ) << QString("*") << QString("Qt Rocks!") << 0;
797 QTest::newRow( "data4" ) << QString(".html") << QString("test.html") << 4;
798 QTest::newRow( "data5" ) << QString(".h") << QString("test.cpp") << -1;
799 QTest::newRow( "data6" ) << QString(".???l") << QString("test.html") << 4;
800 QTest::newRow( "data7" ) << QString("?") << QString("test.html") << 0;
801 QTest::newRow( "data8" ) << QString("?m") << QString("test.html") << 6;
802 QTest::newRow( "data9" ) << QString(".h[a-z]ml") << QString("test.html") << 4;
803 QTest::newRow( "data10" ) << QString(".h[A-Z]ml") << QString("test.html") << -1;
804 QTest::newRow( "data11" ) << QString(".h[A-Z]ml") << QString("test.hTml") << 4;
807 void tst_QRegExp::wildcard()
809 QFETCH( QString, rxp );
810 QFETCH( QString, string );
811 QFETCH( int, foundIndex );
814 r.setPatternSyntax(QRegExp::WildcardUnix);
815 QCOMPARE( r.indexIn( string ), foundIndex );
818 void tst_QRegExp::testEscapingWildcard_data(){
819 QTest::addColumn<QString>("pattern");
820 QTest::addColumn<QString>("teststring");
821 QTest::addColumn<bool>("isMatching");
823 QTest::newRow("[ Not escaped") << "[Qt;" << "[Qt;" << false;
824 QTest::newRow("[ Escaped") << "\\[Qt;" << "[Qt;" << true;
826 QTest::newRow("] Not escaped") << "]Ik;" << "]Ik;" << false;
827 QTest::newRow("] Escaped") << "\\]Ip;" << "]Ip;" << true;
829 QTest::newRow("? Not escaped valid") << "?Ou:" << ".Ou:" << true;
830 QTest::newRow("? Not escaped invalid") << "?Tr;" << "Tr;" << false;
831 QTest::newRow("? Escaped") << "\\?O;" << "?O;" << true;
833 QTest::newRow("[] not escaped") << "[lL]" << "l" << true;
834 QTest::newRow("[] escaped") << "\\[\\]" << "[]" << true;
836 QTest::newRow("case [[]") << "[[abc]" << "[" << true;
837 QTest::newRow("case []abc] match ]") << "[]abc]" << "]" << true;
838 QTest::newRow("case []abc] match a") << "[]abc]" << "a" << true;
839 QTest::newRow("case [abc] match a") << "[abc]" << "a" << true;
840 QTest::newRow("case []] don't match [") << "[]abc]" << "[" << false;
841 QTest::newRow("case [^]abc] match d") << "[^]abc]" << "d" << true;
842 QTest::newRow("case [^]abc] don't match ]") << "[^]abc]" << "]" << false;
844 QTest::newRow("* Not escaped with char") << "*Te;" << "12345Te;" << true;
845 QTest::newRow("* Not escaped without char") << "*Ch;" << "Ch;" << true;
846 QTest::newRow("* Not escaped invalid") << "*Ro;" << "o;" << false;
847 QTest::newRow("* Escaped") << "\\[Cks;" << "[Cks;" << true;
849 QTest::newRow("a true '\\' in input") << "\\Qt;" << "\\Qt;" << true;
850 QTest::newRow("two true '\\' in input") << "\\\\Qt;" << "\\\\Qt;" << true;
851 QTest::newRow("a '\\' at the end") << "\\\\Qt;\\" << "\\\\Qt;\\" << true;
854 void tst_QRegExp::testEscapingWildcard(){
855 QFETCH(QString, pattern);
858 re.setPatternSyntax(QRegExp::WildcardUnix);
860 QFETCH(QString, teststring);
861 QFETCH(bool, isMatching);
862 QCOMPARE(re.exactMatch(teststring), isMatching);
865 void tst_QRegExp::testInvalidWildcard_data(){
866 QTest::addColumn<QString>("pattern");
867 QTest::addColumn<bool>("isValid");
869 QTest::newRow("valid []") << "[abc]" << true;
870 QTest::newRow("invalid [") << "[abc" << false;
871 QTest::newRow("ending [") << "abc[" << false;
872 QTest::newRow("ending ]") << "abc]" << false;
873 QTest::newRow("ending [^") << "abc[^" << false;
874 QTest::newRow("ending [\\") << "abc[\\" << false;
875 QTest::newRow("ending []") << "abc[]" << false;
876 QTest::newRow("ending [[") << "abc[[" << false;
879 void tst_QRegExp::testInvalidWildcard(){
880 QFETCH(QString, pattern);
883 re.setPatternSyntax(QRegExp::Wildcard);
885 QFETCH(bool, isValid);
886 QCOMPARE(re.isValid(), isValid);
889 void tst_QRegExp::caretAnchoredOptimization()
891 QString s = "---babnana----";
892 s.replace( QRegExp("^-*|(-*)$"), "" );
893 QVERIFY(s == "babnana");
895 s = "---babnana----";
896 s.replace( QRegExp("^-*|(-{0,})$"), "" );
897 QVERIFY(s == "babnana");
899 s = "---babnana----";
900 s.replace( QRegExp("^-*|(-{1,})$"), "" );
901 QVERIFY(s == "babnana");
903 s = "---babnana----";
904 s.replace( QRegExp("^-*|(-+)$"), "" );
905 QVERIFY(s == "babnana");
908 void tst_QRegExp::isEmpty()
911 QVERIFY(rx1.isEmpty());
914 QVERIFY(rx2.isEmpty());
917 QVERIFY(rx2.isEmpty());
919 rx2.setPattern("foo");
920 QVERIFY(!rx2.isEmpty());
922 rx2.setPattern(")(");
923 QVERIFY(!rx2.isEmpty());
926 QVERIFY(rx2.isEmpty());
928 rx2.setPatternSyntax(QRegExp::Wildcard);
930 QVERIFY(rx2.isEmpty());
933 static QRegExp re("foo.*bar");
935 void tst_QRegExp::staticRegExp()
937 QVERIFY(re.exactMatch("fooHARRYbar"));
938 // the actual test is that a static regexp should not crash
941 void tst_QRegExp::rainersSlowRegExpCopyBug()
943 // this test should take an extreme amount of time if QRegExp is broken
944 QRegExp original(email);
945 #if defined(Q_OS_WINCE)
946 for (int i = 0; i < 100; ++i) {
948 for (int i = 0; i < 100000; ++i) {
950 QRegExp copy = original;
951 (void)copy.exactMatch("~");
952 QRegExp copy2 = original;
956 void tst_QRegExp::nonExistingBackReferenceBug()
960 QVERIFY(rx.isValid());
961 QCOMPARE(rx.indexIn("<>"), 0);
962 QCOMPARE(rx.capturedTexts(), QStringList("<>"));
967 QVERIFY(rx.isValid());
968 QCOMPARE(rx.indexIn("<>"), 0);
969 QCOMPARE(rx.capturedTexts(), QStringList("<>"));
973 QRegExp rx("(?:<\\1>)\\1\\5\\4");
974 QVERIFY(rx.isValid());
975 QCOMPARE(rx.indexIn("<>"), 0);
976 QCOMPARE(rx.capturedTexts(), QStringList("<>"));
980 class Thread : public QThread
983 Thread(const QRegExp &rx) : rx(rx) {}
993 for (int i = 0; i < 10; ++i)
998 #if defined(Q_OS_WINCE)
999 for (int j = 0; j < 100; ++j) {
1001 for (int j = 0; j < 10000; ++j) {
1003 x = rx.indexIn(str);
1008 void tst_QRegExp::reentrancy()
1010 QRegExp rx("(ab{2,}d?e?f?[g-z]?)c");
1011 Thread *threads[10];
1013 for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i) {
1014 threads[i] = new Thread(rx);
1015 threads[i]->start();
1018 for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
1021 for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
1025 class Thread2 : public QThread
1033 QRegExp rx("(ab{2,}d?e?f?[g-z]?)c");
1034 QString str = "abc";
1035 for (int i = 0; i < 10; ++i)
1040 #if defined(Q_OS_WINCE)
1041 for (int j = 0; j < 100; ++j) {
1043 for (int j = 0; j < 10000; ++j) {
1045 x = rx.indexIn(str);
1050 // Test that multiple threads can construct equal QRegExps.
1051 // (In the current QRegExp design each engine instatance will share
1052 // the same cache key, so the threads will race for the cache entry
1053 // in the global cache.)
1054 void tst_QRegExp::threadsafeEngineCache()
1056 Thread2 *threads[10];
1058 for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i) {
1059 threads[i] = new Thread2();
1060 threads[i]->start();
1063 for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
1066 for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
1071 void tst_QRegExp::prepareEngineOptimization()
1073 QRegExp rx0("(f?)(?:(o?)(o?))?");
1077 QCOMPARE(rx1.capturedTexts(), QStringList() << "" << "" << "" << "");
1078 QCOMPARE(rx1.matchedLength(), -1);
1079 QCOMPARE(rx1.matchedLength(), -1);
1080 QCOMPARE(rx1.captureCount(), 3);
1082 QCOMPARE(rx1.exactMatch("foo"), true);
1083 QCOMPARE(rx1.matchedLength(), 3);
1084 QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
1085 QCOMPARE(rx1.captureCount(), 3);
1086 QCOMPARE(rx1.matchedLength(), 3);
1087 QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
1088 QCOMPARE(rx1.pos(3), 2);
1090 QCOMPARE(rx1.exactMatch("foo"), true);
1091 QCOMPARE(rx1.captureCount(), 3);
1092 QCOMPARE(rx1.matchedLength(), 3);
1093 QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
1094 QCOMPARE(rx1.pos(3), 2);
1098 QCOMPARE(rx1.captureCount(), 3);
1099 QCOMPARE(rx1.matchedLength(), 3);
1100 QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
1101 QCOMPARE(rx1.pos(3), 2);
1103 QCOMPARE(rx2.captureCount(), 3);
1104 QCOMPARE(rx2.matchedLength(), 3);
1105 QCOMPARE(rx2.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
1106 QCOMPARE(rx2.pos(3), 2);
1108 QCOMPARE(rx1.exactMatch("fo"), true);
1109 QCOMPARE(rx1.captureCount(), 3);
1110 QCOMPARE(rx1.matchedLength(), 2);
1111 QCOMPARE(rx1.capturedTexts(), QStringList() << "fo" << "f" << "o" << "");
1112 QCOMPARE(rx1.pos(2), 1);
1115 QVERIFY(rx3.isValid());
1117 QRegExp rx4("foo", Qt::CaseInsensitive, QRegExp::RegExp);
1118 QVERIFY(rx4.isValid());
1120 QRegExp rx5("foo", Qt::CaseInsensitive, QRegExp::RegExp2);
1121 QVERIFY(rx5.isValid());
1123 QRegExp rx6("foo", Qt::CaseInsensitive, QRegExp::FixedString);
1124 QVERIFY(rx6.isValid());
1126 QRegExp rx7("foo", Qt::CaseInsensitive, QRegExp::Wildcard);
1127 QVERIFY(rx7.isValid());
1129 QRegExp rx8("][", Qt::CaseInsensitive, QRegExp::RegExp);
1130 QVERIFY(!rx8.isValid());
1132 QRegExp rx9("][", Qt::CaseInsensitive, QRegExp::RegExp2);
1133 QVERIFY(!rx9.isValid());
1135 QRegExp rx10("][", Qt::CaseInsensitive, QRegExp::Wildcard);
1136 QVERIFY(!rx10.isValid());
1138 QRegExp rx11("][", Qt::CaseInsensitive, QRegExp::FixedString);
1139 QVERIFY(rx11.isValid());
1140 QVERIFY(rx11.exactMatch("]["));
1141 QCOMPARE(rx11.matchedLength(), 2);
1143 rx11.setPatternSyntax(QRegExp::Wildcard);
1144 QVERIFY(!rx11.isValid());
1145 QCOMPARE(rx11.captureCount(), 0);
1146 QCOMPARE(rx11.matchedLength(), -1);
1148 rx11.setPatternSyntax(QRegExp::RegExp);
1149 QVERIFY(!rx11.isValid());
1150 QCOMPARE(rx11.captureCount(), 0);
1151 QCOMPARE(rx11.matchedLength(), -1);
1153 rx11.setPattern("(foo)");
1154 QVERIFY(rx11.isValid());
1155 QCOMPARE(rx11.captureCount(), 1);
1156 QCOMPARE(rx11.matchedLength(), -1);
1158 QCOMPARE(rx11.indexIn("ofoo"), 1);
1159 QCOMPARE(rx11.captureCount(), 1);
1160 QCOMPARE(rx11.matchedLength(), 3);
1162 rx11.setPatternSyntax(QRegExp::RegExp);
1163 QCOMPARE(rx11.captureCount(), 1);
1164 QCOMPARE(rx11.matchedLength(), 3);
1167 This behavior isn't entirely consistent with setPatter(),
1168 setPatternSyntax(), and setCaseSensitivity(), but I'm testing
1169 it here to ensure that it doesn't change subtly in future
1172 rx11.setMinimal(true);
1173 QCOMPARE(rx11.matchedLength(), 3);
1174 rx11.setMinimal(false);
1175 QCOMPARE(rx11.matchedLength(), 3);
1177 rx11.setPatternSyntax(QRegExp::Wildcard);
1178 QCOMPARE(rx11.captureCount(), 0);
1179 QCOMPARE(rx11.matchedLength(), -1);
1181 rx11.setPatternSyntax(QRegExp::RegExp);
1182 QCOMPARE(rx11.captureCount(), 1);
1183 QCOMPARE(rx11.matchedLength(), -1);
1186 void tst_QRegExp::swap()
1188 QRegExp r1(QLatin1String(".*")), r2(QLatin1String("a*"));
1190 QCOMPARE(r1.pattern(),QLatin1String("a*"));
1191 QCOMPARE(r2.pattern(),QLatin1String(".*"));
1194 void tst_QRegExp::operator_eq()
1200 QRegExp rxtable[I * J * K * ELL];
1204 for (int i = 0; i < I; ++i) {
1205 for (int j = 0; j < J; ++j) {
1206 for (int k = 0; k < K; ++k) {
1207 for (int ell = 0; ell < ELL; ++ell) {
1208 Qt::CaseSensitivity cs = i == 0 ? Qt::CaseSensitive : Qt::CaseInsensitive;
1209 QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax(j);
1210 bool minimal = k == 0;
1213 QRegExp rx("foo", cs, syntax);
1214 rx.setMinimal(minimal);
1218 rx.setPattern("bar");
1219 rx.setMinimal(true);
1220 rx.exactMatch("bar");
1221 rx.setCaseSensitivity(cs);
1222 rx.setMinimal(minimal);
1223 rx.setPattern("foo");
1224 rx.setPatternSyntax(syntax);
1225 rx.exactMatch("foo");
1233 for (int i = 0; i < I * J * K * ELL; ++i) {
1234 for (int j = 0; j < I * J * K * ELL; ++j) {
1235 QCOMPARE(rxtable[i] == rxtable[j], i / ELL == j / ELL);
1236 QCOMPARE(rxtable[i] != rxtable[j], i / ELL != j / ELL);
1241 // This test aims to ensure that the values returned by pos() and cap()
1243 void tst_QRegExp::posAndCapConsistency_data()
1245 QTest::addColumn<QString>("reStr");
1246 QTest::addColumn<QString>("text");
1247 QTest::addColumn<int>("matchIndex");
1249 QTest::addColumn<int>("pos0");
1250 QTest::addColumn<int>("pos1");
1251 QTest::addColumn<int>("pos2");
1253 QTest::addColumn<QString>("cap0");
1254 QTest::addColumn<QString>("cap1");
1255 QTest::addColumn<QString>("cap2");
1257 QTest::newRow("no match")
1258 << QString("(a) (b)") << QString("b a") << -1
1259 << -1 << -1 << -1 << QString() << QString() << QString();
1261 QTest::newRow("both captures match")
1262 << QString("(a) (b)") << QString("a b") << 0
1263 << 0 << 0 << 2 << QString("a b") << QString("a") << QString("b");
1265 QTest::newRow("first capture matches @0")
1266 << QString("(a*)|(b*)") << QString("axx") << 0
1267 << 0 << 0 << -1 << QString("a") << QString("a") << QString();
1268 QTest::newRow("second capture matches @0")
1269 << QString("(a*)|(b*)") << QString("bxx") << 0
1270 << 0 << -1 << 0 << QString("b") << QString() << QString("b");
1271 QTest::newRow("first capture empty match @0")
1272 << QString("(a*)|(b*)") << QString("xx") << 0
1273 << 0 << -1 << -1 << QString("") << QString() << QString();
1274 QTest::newRow("second capture empty match @0")
1275 << QString("(a)|(b*)") << QString("xx") << 0
1276 << 0 << -1 << -1 << QString("") << QString() << QString();
1278 QTest::newRow("first capture matches @1")
1279 << QString("x(?:(a*)|(b*))") << QString("-xa") << 1
1280 << 1 << 2 << -1 << QString("xa") << QString("a") << QString();
1281 QTest::newRow("second capture matches @1")
1282 << QString("x(?:(a*)|(b*))") << QString("-xb") << 1
1283 << 1 << -1 << 2 << QString("xb") << QString() << QString("b");
1284 QTest::newRow("first capture empty match @1")
1285 << QString("x(?:(a*)|(b*))") << QString("-xx") << 1
1286 << 1 << -1 << -1 << QString("x") << QString() << QString();
1287 QTest::newRow("second capture empty match @1")
1288 << QString("x(?:(a)|(b*))") << QString("-xx") << 1
1289 << 1 << -1 << -1 << QString("x") << QString() << QString();
1291 QTest::newRow("first capture matches @2")
1292 << QString("(a)|(b)") << QString("xxa") << 2
1293 << 2 << 2 << -1 << QString("a") << QString("a") << QString();
1294 QTest::newRow("second capture matches @2")
1295 << QString("(a)|(b)") << QString("xxb") << 2
1296 << 2 << -1 << 2 << QString("b") << QString() << QString("b");
1297 QTest::newRow("no match - with options")
1298 << QString("(a)|(b)") << QString("xx") << -1
1299 << -1 << -1 << -1 << QString() << QString() << QString();
1303 void tst_QRegExp::posAndCapConsistency()
1305 QFETCH( QString, reStr );
1306 QFETCH( QString, text );
1307 QFETCH( int, matchIndex );
1308 QFETCH( int, pos0 );
1309 QFETCH( int, pos1 );
1310 QFETCH( int, pos2 );
1311 QFETCH( QString, cap0 );
1312 QFETCH( QString, cap1 );
1313 QFETCH( QString, cap2 );
1316 QCOMPARE(re.captureCount(), 2);
1317 QCOMPARE(re.capturedTexts().size(), 3);
1319 QCOMPARE(re.indexIn(text), matchIndex);
1321 QCOMPARE( re.pos(0), pos0 );
1322 QCOMPARE( re.pos(1), pos1 );
1323 QCOMPARE( re.pos(2), pos2 );
1325 QCOMPARE( re.cap(0).isNull(), cap0.isNull() );
1326 QCOMPARE( re.cap(0), cap0 );
1327 QCOMPARE( re.cap(1).isNull(), cap1.isNull() );
1328 QCOMPARE( re.cap(1), cap1 );
1329 QCOMPARE( re.cap(2).isNull(), cap2.isNull() );
1330 QCOMPARE( re.cap(2), cap2 );
1333 void tst_QRegExp::interval()
1336 QRegExp exp("a{0,1}");
1337 QVERIFY(exp.isValid());
1340 QRegExp exp("a{1,1}");
1341 QVERIFY(exp.isValid());
1344 QRegExp exp("a{1,0}");
1345 QVERIFY(!exp.isValid());
1349 void tst_QRegExp::validityCheck_data()
1351 QTest::addColumn<QString>("pattern");
1352 QTest::addColumn<bool>("validity");
1353 QTest::newRow("validity01") << QString() << true;
1354 QTest::newRow("validity02") << QString("abc.*abc") << true;
1355 QTest::newRow("validity03") << QString("[a-z") << false;
1356 QTest::newRow("validity04") << QString("a(b") << false;
1359 void tst_QRegExp::validityCheck()
1361 QFETCH(QString, pattern);
1363 QRegExp rx(pattern);
1364 QTEST(rx.isValid(), "validity");
1365 QCOMPARE(rx.matchedLength(), -1);
1366 QCOMPARE(rx.pos(), -1);
1367 QCOMPARE(rx.cap(), QString(""));
1370 QTEST(rx2.isValid(), "validity");
1371 QCOMPARE(rx2.matchedLength(), -1);
1372 QCOMPARE(rx2.pos(), -1);
1373 QCOMPARE(rx2.cap(), QString(""));
1377 QTEST_APPLESS_MAIN(tst_QRegExp)
1378 #include "tst_qregexp.moc"