2 // MonoTests.System.Text.RegularExpressions misc. test cases
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // (c) Copyright 2003,2004 Novell, Inc. (http://www.novell.com)
12 using System.Text.RegularExpressions;
14 using NUnit.Framework;
16 namespace MonoTests.System.Text.RegularExpressions
19 public class RegexBugs
22 public void SplitGroup ()
24 string [] splitResult = new Regex ("-").Split ("a-bcd-e-fg");
25 string [] expected = new string [] {"a", "bcd", "e", "fg"};
26 int length = expected.Length;
27 Assert.AreEqual (length, splitResult.Length, "#1");
28 for (int i = 0; i < length; i++)
29 Assert.AreEqual (expected [i], splitResult [i], "#2:" + i);
31 splitResult = new Regex ("(-)").Split ("a-bcd-e-fg");
32 expected = new string [] {"a", "-", "bcd", "-", "e", "-", "fg"};
33 length = expected.Length;
34 Assert.AreEqual (length, splitResult.Length, "#3");
35 for (int i = 0; i < length; i++)
36 Assert.AreEqual (expected [i], splitResult [i], "#4:" + i);
38 splitResult = new Regex ("(-)b(c)").Split ("a-bcd-e-fg");
39 expected = new string [] {"a", "-", "c", "d-e-fg" };
40 length = expected.Length;
41 Assert.AreEqual (length, splitResult.Length, "#5");
42 for (int i = 0; i < length; i++)
43 Assert.AreEqual (expected [i], splitResult [i], "#6:" + i);
45 splitResult = new Regex ("-").Split ("a-bcd-e-fg-");
46 expected = new string [] {"a", "bcd", "e", "fg", ""};
47 length = expected.Length;
48 Assert.AreEqual (length, splitResult.Length, "#7");
49 for (int i = 0; i < length; i++)
50 Assert.AreEqual (expected [i], splitResult [i], "#8:" + i);
54 public void MathEmptyGroup ()
56 string str = "Match something from here.";
58 Assert.IsFalse (Regex.IsMatch(str, @"(something|dog)$"), "#1");
59 Assert.IsTrue (Regex.IsMatch (str, @"(|something|dog)$"), "#2");
60 Assert.IsTrue (Regex.IsMatch (str, @"(something||dog)$"), "#3");
61 Assert.IsTrue (Regex.IsMatch (str, @"(something|dog|)$"), "#4");
63 Assert.IsTrue (Regex.IsMatch (str, @"(something|dog)*"), "#5");
64 Assert.IsTrue (Regex.IsMatch (str, @"(|something|dog)*"), "#6");
65 Assert.IsTrue (Regex.IsMatch (str, @"(something||dog)*"), "#7");
66 Assert.IsTrue (Regex.IsMatch (str, @"(something|dog|)*"), "#8");
68 Assert.IsTrue (Regex.IsMatch (str, @"(something|dog)*$"), "#9");
69 Assert.IsTrue (Regex.IsMatch (str, @"(|something|dog)*$"), "#10");
70 Assert.IsTrue (Regex.IsMatch (str, @"(something||dog)*$"), "#11");
71 Assert.IsTrue (Regex.IsMatch (str, @"(something|dog|)*$"), "#12");
77 Regex regVar = new Regex(@"{\w+}");
78 Match m = regVar.Match ("{ }");
79 Assert.IsFalse (m.Success);
83 public void WhiteSpaceGroupped ()
86 string p = @"[\s\S]"; // =Category.Any
87 Assert.IsTrue (Regex.IsMatch (s, p));
91 public void CharacterClassParse ()
93 var foo = new Regex("[\\177-\\377]");
97 public void RangeIgnoreCase()
99 string str = "AAABBBBAAA" ;
100 Assert.IsTrue (Regex.IsMatch(str, @"[A-F]+", RegexOptions.IgnoreCase), "#A1");
101 Assert.IsTrue (Regex.IsMatch (str, @"[a-f]+", RegexOptions.IgnoreCase), "#A2");
102 Assert.IsTrue (Regex.IsMatch (str, @"[A-Fa-f]+", RegexOptions.IgnoreCase), "#A3");
103 Assert.IsTrue (Regex.IsMatch (str, @"[AB]+", RegexOptions.IgnoreCase), "#A4");
104 Assert.IsTrue (Regex.IsMatch (str, @"[A-B]+", RegexOptions.IgnoreCase), "#A5");
107 Assert.IsTrue (Regex.IsMatch (str, @"[A-F]+", RegexOptions.IgnoreCase), "#B1");
108 Assert.IsTrue (Regex.IsMatch (str, @"[a-f]+", RegexOptions.IgnoreCase), "#B2");
109 Assert.IsTrue (Regex.IsMatch (str, @"[A-Fa-f]+", RegexOptions.IgnoreCase), "#B3");
110 Assert.IsTrue (Regex.IsMatch (str, @"[AB]+", RegexOptions.IgnoreCase), "#B4");
111 Assert.IsTrue (Regex.IsMatch (str, @"[A-B]+", RegexOptions.IgnoreCase), "#B5");
114 Assert.IsTrue (Regex.IsMatch (str, @"[A-a]+", RegexOptions.IgnoreCase), "#C");
117 Assert.IsTrue (Regex.IsMatch (str, @"[A-a]+", RegexOptions.IgnoreCase), "#D");
121 public void Escape0 ()
123 Regex r = new Regex(@"^[\s\0]*$");
124 Assert.IsTrue (r.Match(" \0").Success);
127 [Test] // bug #432172
128 public void NoBitmap ()
131 new Regex ("([^a-zA-Z_0-9])+", RegexOptions.Compiled);
132 Assert.AreEqual ("--", rx.Match ("A--B-").Value);
136 public void MultipleMatches()
138 Regex regex = new Regex (@"^(?'path'.*(\\|/)|(/|\\))(?'file'.*)$");
139 Match match = regex.Match (@"d:\Temp\SomeDir\SomeDir\bla.xml");
141 Assert.AreEqual (5, match.Groups.Count, "#1");
142 Assert.AreEqual ("1", regex.GroupNameFromNumber (1), "#2");
143 Assert.AreEqual ("2", regex.GroupNameFromNumber (2), "#3");
144 Assert.AreEqual ("path", regex.GroupNameFromNumber (3), "#4");
145 Assert.AreEqual ("file", regex.GroupNameFromNumber (4), "#5");
146 Assert.AreEqual ("\\", match.Groups [1].Value, "#6");
147 Assert.AreEqual (string.Empty, match.Groups [2].Value, "#7");
148 Assert.AreEqual (@"d:\Temp\SomeDir\SomeDir\", match.Groups [3].Value, "#8");
149 Assert.AreEqual ("bla.xml", match.Groups [4].Value, "#9");
153 public void SameNameGroups ()
155 string rex = "link\\s*rel\\s*=\\s*[\"']?alternate[\"']?\\s*";
156 rex += "type\\s*=\\s*[\"']?text/xml[\"']?\\s*href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|'(?<1>[^']*)'|(?<1>\\S+))";
157 new Regex (rex, RegexOptions.IgnoreCase);
161 public void UndefinedGroup ()
163 Regex regex = new Regex( "[A-Za-z_0-9]" );
164 Match m = regex.Match( "123456789abc" );
165 Group g = m.Groups["not_defined"];
166 Assert.IsNotNull (g, "#1");
167 Assert.AreEqual (0, g.Index, "#2");
168 Assert.AreEqual (0, g.Length, "#3");
169 Assert.AreEqual (string.Empty, g.Value, "#4");
170 Assert.IsFalse (g.Success, "#5");
171 Assert.IsNotNull (g.Captures, "#6");
172 Assert.AreEqual (0, g.Captures.Count, "#7");
176 public void Quantifiers1 ()
178 Regex re = new Regex ("[\\w\\W]{8,32}");
179 Match m = re.Match (new string ('1', 7));
180 Assert.IsFalse (m.Success);
184 public void Quantifiers2 ()
186 Regex re = new Regex ("[\\w\\W]{8,32}");
187 Match m = re.Match (new string ('1', 8));
188 Assert.IsTrue (m.Success);
192 public void Quantifiers3 ()
194 Regex re = new Regex ("[\\w\\W]{8,32}");
195 Match m = re.Match (new string ('1', 16));
196 Assert.IsTrue (m.Success);
200 public void Quantifiers4 ()
202 Regex re = new Regex ("[\\w\\W]{8,32}");
203 Match m = re.Match (new string ('1', 32));
204 Assert.IsTrue (m.Success);
208 public void Quantifiers5 ()
210 Regex re = new Regex ("[\\w\\W]{8,32}");
211 Match m = re.Match (new string ('1', 33));
212 Assert.IsTrue (m.Success);
216 public void CategoryAndNegated () // Was a regression after first attemp to fix 59150.
218 string text = "<?xml version=\"1.0\"?>";
219 Regex re = new Regex ("<\\s*(\\/?)\\s*([\\s\\S]*?)\\s*(\\/?)\\s*>");
220 text = re.Replace (text, "{blue:<$1}{maroon:$2}{blue:$3>}");
221 Assert.AreEqual ("{blue:<}{maroon:?xml version=\"1.0\"?}{blue:>}", text);
225 public void BackSpace ()
227 string text = "Go, \bNo\bGo" ;
228 Regex re = new Regex(@"\b[\b]");
229 text = re.Replace(text, " ");
230 Assert.AreEqual ("Go, \bNo Go", text);
234 public void ReplaceNegOneAndStartat ()
236 string text = "abcdeeee";
237 Regex re = new Regex("e+");
238 text = re.Replace(text, "e", -1, 4);
239 Assert.AreEqual ("abcde", text);
243 public void SplitInfiniteLoop ()
245 string ss = "a b c d e";
246 string [] words = Regex.Split (ss, "[ \t\n\r]*");
247 Assert.AreEqual (11, words.Length, "#1");
248 Assert.AreEqual (string.Empty, words [0], "#2");
249 Assert.AreEqual ("a", words [1], "#3");
250 Assert.AreEqual (string.Empty, words [2], "#4");
251 Assert.AreEqual ("b", words [3], "#5");
252 Assert.AreEqual (string.Empty, words [4], "#6");
253 Assert.AreEqual ("c", words [5], "#7");
254 Assert.AreEqual (string.Empty, words [6], "#8");
255 Assert.AreEqual ("d", words [7], "#9");
256 Assert.AreEqual (string.Empty, words [8], "#10");
257 Assert.AreEqual ("e", words [9], "#11");
258 Assert.AreEqual (string.Empty, words [10], "#12");
262 public void CaseAndSearch ()
264 string test1 = @"
\f!E ZWEITBAD :REGLER-PARAMETER 20.10.2004 SEITE 1";
265 string test2 = @" REGLER-PARAMETER ";
266 string test3 = @"REGLER-PARAMETER ";
267 Regex x = new Regex ("REGLER-PARAMETER",RegexOptions.IgnoreCase|RegexOptions.Compiled);
269 Match m = x.Match (test1);
270 Assert.IsTrue (m.Success, "#1");
273 Assert.IsTrue (m.Success, "#2");
276 Assert.IsTrue (m.Success, "#3");
280 public void QuantifiersParseError ()
289 public void NameLookupInEmptyMatch ()
291 Regex regTime = new Regex (
292 @"(?<hour>[0-9]{1,2})([\:](?<minute>[0-9]{1,2})){0,1}([\:](?<second>[0-9]{1,2})){0,1}\s*(?<ampm>(?i:(am|pm)){0,1})");
294 Match mTime = regTime.Match("");
295 Assert.AreEqual ("", mTime.Groups["hour"].Value, "#A1");
296 Assert.AreEqual ("", mTime.Groups ["minute"].Value, "#A2");
297 Assert.AreEqual ("", mTime.Groups ["second"].Value, "#A3");
298 Assert.AreEqual ("", mTime.Groups ["ampm"].Value, "#A4");
300 mTime = regTime.Match("12:00 pm");
301 Assert.AreEqual ("12", mTime.Groups ["hour"].Value, "#B1");
302 Assert.AreEqual ("00", mTime.Groups ["minute"].Value, "#B2");
303 Assert.AreEqual ("", mTime.Groups ["second"].Value, "#B3");
304 Assert.AreEqual ("pm", mTime.Groups ["ampm"].Value, "#B4");
308 public void HangingHyphens ()
310 Assert.IsTrue (Regex.IsMatch ("mT1[", @"m[0-9A-Za-z_-]+\["), "#A1");
311 Assert.IsTrue (Regex.IsMatch ("mT1[", @"m[-0-9A-Za-z_]+\["), "#A2");
313 Assert.IsTrue (Regex.IsMatch ("-a;", @"[--a]{3}"), "#B1");
314 Assert.IsTrue (Regex.IsMatch ("-&,", @"[&--]{3}"), "#B2");
316 Assert.IsTrue (Regex.IsMatch ("abcz-", @"[a-c-z]{5}"), "#C1");
317 Assert.IsFalse (Regex.IsMatch ("defghijklmnopqrstuvwxy", @"[a-c-z]"), "#C2");
319 Assert.IsTrue (Regex.IsMatch ("abcxyz-", @"[a-c-x-z]{7}"), "#D1");
320 Assert.IsFalse (Regex.IsMatch ("defghijklmnopqrstuvw", @"[a-c-x-z]"), "#D2");
322 Assert.IsTrue (Regex.IsMatch (" \tz-", @"[\s-z]{4}"), "#E1");
323 Assert.IsFalse (Regex.IsMatch ("abcdefghijklmnopqrstuvwxy", @"[\s-z]"), "#E2");
326 [Test, ExpectedException (typeof (ArgumentException))]
327 public void HangingHyphen1 ()
329 Regex.IsMatch ("foobar", @"[a-\s]");
333 public void Bug313642 ()
335 Regex r = new Regex ("(?<a>c)");
336 Match m = r.Match ("a");
337 Assert.AreEqual (1, m.Groups.Count, "#1");
338 Assert.AreEqual (0, m.Groups [0].Captures.Count, "#2");
339 Assert.AreEqual (0, m.Groups [0].Index, "#3");
340 Assert.AreEqual (0, m.Groups [0].Length, "#4");
341 Assert.IsFalse (m.Groups [0].Success, "#5");
342 Assert.AreEqual (string.Empty, m.Groups [0].Value, "#6");
346 public void Bug77487 ()
348 Assert.IsTrue (Regex.IsMatch ("a a", "^(a[^a]*)*a$"), "#1");
349 Assert.IsTrue (Regex.IsMatch ("a a", "^(a *)*a$"), "#2");
350 Assert.IsTrue (Regex.IsMatch ("a a", "(a[^a]*)+a"), "#3");
351 Assert.IsTrue (Regex.IsMatch ("a a", "(a *)+a"), "#4");
355 public void Bug69269 ()
357 string s = "CREATE aa\faa; CREATE bb\nbb; CREATE cc\rcc; CREATE dd\tdd; CREATE ee\vee;";
358 Assert.AreEqual (5, Regex.Matches(s, @"CREATE[\s\S]+?;").Count, "#1");
359 Assert.AreEqual (5, Regex.Matches (s, @"CREATE[ \f\n\r\t\v\S]+?;").Count, "#2");
363 public void Bug76345 ()
366 string s1 = "'asdf'";
367 string s2 = "'as,'df'";
369 m = new Regex("'.*?'").Match(s1);
370 Assert.IsTrue (m.Success, "#A1");
371 Assert.AreEqual (s1, m.Value, "#A2");
373 m = new Regex("'[^,].*?'").Match(s1);
374 Assert.IsTrue (m.Success, "#B1");
375 Assert.AreEqual (s1, m.Value, "#B2");
377 m = new Regex("'.*?[^,]'").Match(s1);
378 Assert.IsTrue (m.Success, "#C1");
379 Assert.AreEqual (s1, m.Value, "#C2");
381 m = new Regex("'.*?[^,]'").Match(s2);
382 Assert.IsTrue (m.Success, "#D1");
383 Assert.AreEqual (s2, m.Value, "#D2");
387 public void Bug78007 ()
389 string test = "head><html>";
390 string pattern = @"\Ahead>\<html\>";
391 Regex r = new Regex (pattern);
392 Match m = r.Match (test);
393 Assert.IsTrue (m.Success, "#A1");
394 Assert.AreEqual (0, m.Index, "#A2");
395 Assert.AreEqual (14, m.Length, "#A3");
398 Assert.IsFalse (m.Success, "#B");
402 public void Bug439947 ()
405 r = new Regex ("(?<=^|/)[^/]*\\.cs$", RegexOptions.None);
406 Assert.IsTrue (r.IsMatch ("z/text2.cs"));
408 r = new Regex ("(?<=^|/)[^/]*\\.cs$", RegexOptions.Compiled);
409 Assert.IsTrue (r.IsMatch ("z/text2.cs"));
413 public void bug443841 ()
415 string numberString = @"[0-9]+";
416 string doubleString = string.Format (@" *[+-]? *{0}(\.{0})?([eE][+-]?{0})? *",
418 string vector1To3String = string.Format (@"{0}(,{0}(,{0})?)?",
421 MatchCollection matches;
423 r = new Regex (string.Format ("^{0}$", vector1To3String));
424 Assert.IsTrue (r.IsMatch ("1"), "#A1");
425 matches = r.Matches ("1");
426 Assert.AreEqual (1, matches.Count, "#A2");
427 Assert.AreEqual ("1", matches [0].Value, "#A3");
429 r = new Regex (string.Format ("^{0}$", vector1To3String),
430 RegexOptions.Compiled);
431 Assert.IsTrue (r.IsMatch ("1"), "#B1");
432 matches = r.Matches ("1");
433 Assert.AreEqual (1, matches.Count, "#B2");
434 Assert.AreEqual ("1", matches [0].Value, "#B3");
438 public void CharClassWithIgnoreCase ()
440 string str = "Foobar qux";
441 Regex re = new Regex (@"[a-z\s]*", RegexOptions.IgnoreCase);
442 Match m = re.Match (str);
443 Assert.AreEqual (str, m.Value);
447 public void No65535Limit ()
451 Kill65535_1 (131071);
452 Kill65535_1 (131072);
456 Kill65535_2 (131066);
457 Kill65535_2 (131067);
461 public void GroupNumbers ()
463 GroupNumbers_1 ("a", 1);
464 GroupNumbers_1 ("(a)", 2);
465 GroupNumbers_1 ("(a)(b)", 3);
466 GroupNumbers_1 ("(a)|(b)", 3);
467 GroupNumbers_1 ("((a)(b))(c)", 5);
471 public void Trials ()
473 foreach (RegexTrial trial in trials)
478 public void Bug80554_0 ()
480 bug80554_trials [0].Execute ();
484 public void Bug80554_1 ()
486 bug80554_trials [1].Execute ();
490 public void Bug80554_2 ()
492 bug80554_trials [2].Execute ();
496 public void Bug80554_3 ()
498 bug80554_trials [3].Execute ();
502 public void Bug432172 ()
504 new Regex ("^(else|elif|except|finally)([^a-zA-Z_0-9]).*", RegexOptions.Compiled);
509 public void Bug610587_RepetitionOfPositionAssertion ()
511 Assert.AreEqual ("888", Regex.Match("888", "^*8.*").Value);
515 public void XamarinBug2663 ()
517 var r = new Regex("^(S|SW)?$");
518 Match m = r.Match("SW");
519 Assert.AreEqual(true, m.Success, "#Bug2663-a");
521 Assert.AreEqual(true, m.Success, "#Bug2663-b");
523 Assert.AreEqual(false, m.Success, "#Bug2663-c");
525 Assert.AreEqual(false, m.Success, "#Bug2663-d");
527 r=new Regex("^([0-9]{4})(N|E|W|S|NE|NW|SE|SW|NDV)?$");
529 m = r.Match("2663N");
530 Assert.AreEqual(true, m.Success, "#Bug2663-e");
531 m = r.Match("2663E");
532 Assert.AreEqual(true, m.Success, "#Bug2663-f");
533 m = r.Match("2663W");
534 Assert.AreEqual(true, m.Success, "#Bug2663-g");
535 m = r.Match("2663S");
536 Assert.AreEqual(true, m.Success, "#Bug2663-h");
537 m = r.Match("2663NE");
538 Assert.AreEqual(true, m.Success, "#Bug2663-i");
539 m = r.Match("2663NW");
540 Assert.AreEqual(true, m.Success, "#Bug2663-j");
541 m = r.Match("2663SE");
542 Assert.AreEqual(true, m.Success, "#Bug2663-k");
543 m = r.Match("2663SW");
544 Assert.AreEqual(true, m.Success, "#Bug2663-l");
545 m = r.Match("2663NDV");
546 Assert.AreEqual(true, m.Success, "#Bug2663-m");
548 m = r.Match("2663NF");
549 Assert.AreEqual(false, m.Success, "#Bug2663-n");
550 m = r.Match("2663EF");
551 Assert.AreEqual(false, m.Success, "#Bug2663-o");
552 m = r.Match("2663WF");
553 Assert.AreEqual(false, m.Success, "#Bug2663-p");
554 m = r.Match("2663SF");
555 Assert.AreEqual(false, m.Success, "#Bug2663-q");
556 m = r.Match("2663NEF");
557 Assert.AreEqual(false, m.Success, "#Bug2663-r");
558 m = r.Match("2663NWF");
559 Assert.AreEqual(false, m.Success, "#Bug2663-s");
560 m = r.Match("2663SEF");
561 Assert.AreEqual(false, m.Success, "#Bug2663-t");
562 m = r.Match("2663SWF");
563 Assert.AreEqual(false, m.Success, "#Bug2663-u");
564 m = r.Match("2663NDVF");
565 Assert.AreEqual(false, m.Success, "#Bug2663-v");
569 void Kill65535_1 (int length)
571 StringBuilder sb = new StringBuilder ("x");
572 sb.Append ('a', length);
574 string teststring = sb.ToString ();
575 Regex regex = new Regex (@"xa*y");
576 Match m = regex.Match (teststring);
577 Assert.IsTrue (m.Success, "#1:" + length);
578 Assert.AreEqual (0, m.Index, "#2:" + length);
579 Assert.AreEqual (teststring.Length, m.Length, "#3:" + length);
582 void Kill65535_2 (int length)
584 StringBuilder sb = new StringBuilder ("xaaaax");
585 sb.Append ('a', length);
587 string teststring = sb.ToString ();
588 Regex regex = new Regex (@"x.*y");
589 Match m = regex.Match(teststring);
590 Assert.IsTrue (m.Success, "#1:" + length);
591 Assert.AreEqual (0, m.Index, "#2:" + length);
592 Assert.AreEqual (teststring.Length, m.Length, "#3:" + length);
595 void GroupNumbers_1 (string s, int n)
597 Regex r = new Regex (s);
598 int [] grps = r.GetGroupNumbers ();
599 Assert.AreEqual (n, grps.Length, "#1:" + r);
602 for (int i = 0; i < grps.Length; ++i) {
604 // group numbers are unique
605 for (int j = 0; j < i; ++j)
606 Assert.IsTrue (grps [i] != grps [j], "#2:" + r + " (" + i + "," + j + ")");
608 // no gaps in group numbering
609 Assert.AreEqual ((n * (n - 1)) / 2, sum, "#3:" + r);
613 static string bug80554_s = @"(?(static)|(.*))(static)";
614 static RegexTrial[] bug80554_trials = {
615 new RegexTrial (bug80554_s, RegexOptions.None, "static", "Pass. Group[0]=(0,6) Group[1]= Group[2]=(0,6)"),
616 new RegexTrial (bug80554_s, RegexOptions.None, "hydrostatic", "Pass. Group[0]=(0,11) Group[1]=(0,5) Group[2]=(5,6)"),
617 new RegexTrial (bug80554_s, RegexOptions.None, "statics", "Pass. Group[0]=(0,6) Group[1]= Group[2]=(0,6)"),
618 new RegexTrial (bug80554_s, RegexOptions.None, "dynamic", "Fail.")
621 static RegexTrial[] trials = {
622 new RegexTrial (@"^[^.\d]*(\d+)(?:\D+(\d+))?", RegexOptions.None, "MD 9.18", "Pass. Group[0]=(0,7) Group[1]=(3,1) Group[2]=(5,2)"),
623 new RegexTrial (@"(.*:|.*)(DirName)", RegexOptions.Compiled, "/home/homedir/DirName", "Pass. Group[0]=(0,21) Group[1]=(0,14) Group[2]=(14,7)")