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 RangeIgnoreCase()
93 string str = "AAABBBBAAA" ;
94 Assert.IsTrue (Regex.IsMatch(str, @"[A-F]+", RegexOptions.IgnoreCase), "#A1");
95 Assert.IsTrue (Regex.IsMatch (str, @"[a-f]+", RegexOptions.IgnoreCase), "#A2");
96 Assert.IsTrue (Regex.IsMatch (str, @"[A-Fa-f]+", RegexOptions.IgnoreCase), "#A3");
97 Assert.IsTrue (Regex.IsMatch (str, @"[AB]+", RegexOptions.IgnoreCase), "#A4");
98 Assert.IsTrue (Regex.IsMatch (str, @"[A-B]+", RegexOptions.IgnoreCase), "#A5");
101 Assert.IsTrue (Regex.IsMatch (str, @"[A-F]+", RegexOptions.IgnoreCase), "#B1");
102 Assert.IsTrue (Regex.IsMatch (str, @"[a-f]+", RegexOptions.IgnoreCase), "#B2");
103 Assert.IsTrue (Regex.IsMatch (str, @"[A-Fa-f]+", RegexOptions.IgnoreCase), "#B3");
104 Assert.IsTrue (Regex.IsMatch (str, @"[AB]+", RegexOptions.IgnoreCase), "#B4");
105 Assert.IsTrue (Regex.IsMatch (str, @"[A-B]+", RegexOptions.IgnoreCase), "#B5");
108 Assert.IsTrue (Regex.IsMatch (str, @"[A-a]+", RegexOptions.IgnoreCase), "#C");
111 Assert.IsTrue (Regex.IsMatch (str, @"[A-a]+", RegexOptions.IgnoreCase), "#D");
115 public void Escape0 ()
117 Regex r = new Regex(@"^[\s\0]*$");
118 Assert.IsTrue (r.Match(" \0").Success);
121 [Test] // bug #432172
122 public void NoBitmap ()
125 new Regex ("([^a-zA-Z_0-9])+", RegexOptions.Compiled);
126 Assert.AreEqual ("--", rx.Match ("A--B-").Value);
130 public void MultipleMatches()
132 Regex regex = new Regex (@"^(?'path'.*(\\|/)|(/|\\))(?'file'.*)$");
133 Match match = regex.Match (@"d:\Temp\SomeDir\SomeDir\bla.xml");
135 Assert.AreEqual (5, match.Groups.Count, "#1");
136 Assert.AreEqual ("1", regex.GroupNameFromNumber (1), "#2");
137 Assert.AreEqual ("2", regex.GroupNameFromNumber (2), "#3");
138 Assert.AreEqual ("path", regex.GroupNameFromNumber (3), "#4");
139 Assert.AreEqual ("file", regex.GroupNameFromNumber (4), "#5");
140 Assert.AreEqual ("\\", match.Groups [1].Value, "#6");
141 Assert.AreEqual (string.Empty, match.Groups [2].Value, "#7");
142 Assert.AreEqual (@"d:\Temp\SomeDir\SomeDir\", match.Groups [3].Value, "#8");
143 Assert.AreEqual ("bla.xml", match.Groups [4].Value, "#9");
147 public void SameNameGroups ()
149 string rex = "link\\s*rel\\s*=\\s*[\"']?alternate[\"']?\\s*";
150 rex += "type\\s*=\\s*[\"']?text/xml[\"']?\\s*href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|'(?<1>[^']*)'|(?<1>\\S+))";
151 new Regex (rex, RegexOptions.IgnoreCase);
155 public void UndefinedGroup ()
157 Regex regex = new Regex( "[A-Za-z_0-9]" );
158 Match m = regex.Match( "123456789abc" );
159 Group g = m.Groups["not_defined"];
160 Assert.IsNotNull (g, "#1");
161 Assert.AreEqual (0, g.Index, "#2");
162 Assert.AreEqual (0, g.Length, "#3");
163 Assert.AreEqual (string.Empty, g.Value, "#4");
164 Assert.IsFalse (g.Success, "#5");
165 Assert.IsNotNull (g.Captures, "#6");
166 Assert.AreEqual (0, g.Captures.Count, "#7");
170 public void Quantifiers1 ()
172 Regex re = new Regex ("[\\w\\W]{8,32}");
173 Match m = re.Match (new string ('1', 7));
174 Assert.IsFalse (m.Success);
178 public void Quantifiers2 ()
180 Regex re = new Regex ("[\\w\\W]{8,32}");
181 Match m = re.Match (new string ('1', 8));
182 Assert.IsTrue (m.Success);
186 public void Quantifiers3 ()
188 Regex re = new Regex ("[\\w\\W]{8,32}");
189 Match m = re.Match (new string ('1', 16));
190 Assert.IsTrue (m.Success);
194 public void Quantifiers4 ()
196 Regex re = new Regex ("[\\w\\W]{8,32}");
197 Match m = re.Match (new string ('1', 32));
198 Assert.IsTrue (m.Success);
202 public void Quantifiers5 ()
204 Regex re = new Regex ("[\\w\\W]{8,32}");
205 Match m = re.Match (new string ('1', 33));
206 Assert.IsTrue (m.Success);
210 public void CategoryAndNegated () // Was a regression after first attemp to fix 59150.
212 string text = "<?xml version=\"1.0\"?>";
213 Regex re = new Regex ("<\\s*(\\/?)\\s*([\\s\\S]*?)\\s*(\\/?)\\s*>");
214 text = re.Replace (text, "{blue:<$1}{maroon:$2}{blue:$3>}");
215 Assert.AreEqual ("{blue:<}{maroon:?xml version=\"1.0\"?}{blue:>}", text);
219 public void BackSpace ()
221 string text = "Go, \bNo\bGo" ;
222 Regex re = new Regex(@"\b[\b]");
223 text = re.Replace(text, " ");
224 Assert.AreEqual ("Go, \bNo Go", text);
228 public void ReplaceNegOneAndStartat ()
230 string text = "abcdeeee";
231 Regex re = new Regex("e+");
232 text = re.Replace(text, "e", -1, 4);
233 Assert.AreEqual ("abcde", text);
237 public void SplitInfiniteLoop ()
239 string ss = "a b c d e";
240 string [] words = Regex.Split (ss, "[ \t\n\r]*");
241 Assert.AreEqual (11, words.Length, "#1");
242 Assert.AreEqual (string.Empty, words [0], "#2");
243 Assert.AreEqual ("a", words [1], "#3");
244 Assert.AreEqual (string.Empty, words [2], "#4");
245 Assert.AreEqual ("b", words [3], "#5");
246 Assert.AreEqual (string.Empty, words [4], "#6");
247 Assert.AreEqual ("c", words [5], "#7");
248 Assert.AreEqual (string.Empty, words [6], "#8");
249 Assert.AreEqual ("d", words [7], "#9");
250 Assert.AreEqual (string.Empty, words [8], "#10");
251 Assert.AreEqual ("e", words [9], "#11");
252 Assert.AreEqual (string.Empty, words [10], "#12");
256 public void CaseAndSearch ()
258 string test1 = @"
\f!E ZWEITBAD :REGLER-PARAMETER 20.10.2004 SEITE 1";
259 string test2 = @" REGLER-PARAMETER ";
260 string test3 = @"REGLER-PARAMETER ";
261 Regex x = new Regex ("REGLER-PARAMETER",RegexOptions.IgnoreCase|RegexOptions.Compiled);
263 Match m = x.Match (test1);
264 Assert.IsTrue (m.Success, "#1");
267 Assert.IsTrue (m.Success, "#2");
270 Assert.IsTrue (m.Success, "#3");
274 public void QuantifiersParseError ()
283 public void NameLookupInEmptyMatch ()
285 Regex regTime = new Regex (
286 @"(?<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})");
288 Match mTime = regTime.Match("");
289 Assert.AreEqual ("", mTime.Groups["hour"].Value, "#A1");
290 Assert.AreEqual ("", mTime.Groups ["minute"].Value, "#A2");
291 Assert.AreEqual ("", mTime.Groups ["second"].Value, "#A3");
292 Assert.AreEqual ("", mTime.Groups ["ampm"].Value, "#A4");
294 mTime = regTime.Match("12:00 pm");
295 Assert.AreEqual ("12", mTime.Groups ["hour"].Value, "#B1");
296 Assert.AreEqual ("00", mTime.Groups ["minute"].Value, "#B2");
297 Assert.AreEqual ("", mTime.Groups ["second"].Value, "#B3");
298 Assert.AreEqual ("pm", mTime.Groups ["ampm"].Value, "#B4");
302 public void HangingHyphens ()
304 Assert.IsTrue (Regex.IsMatch ("mT1[", @"m[0-9A-Za-z_-]+\["), "#A1");
305 Assert.IsTrue (Regex.IsMatch ("mT1[", @"m[-0-9A-Za-z_]+\["), "#A2");
307 Assert.IsTrue (Regex.IsMatch ("-a;", @"[--a]{3}"), "#B1");
308 Assert.IsTrue (Regex.IsMatch ("-&,", @"[&--]{3}"), "#B2");
310 Assert.IsTrue (Regex.IsMatch ("abcz-", @"[a-c-z]{5}"), "#C1");
311 Assert.IsFalse (Regex.IsMatch ("defghijklmnopqrstuvwxy", @"[a-c-z]"), "#C2");
313 Assert.IsTrue (Regex.IsMatch ("abcxyz-", @"[a-c-x-z]{7}"), "#D1");
314 Assert.IsFalse (Regex.IsMatch ("defghijklmnopqrstuvw", @"[a-c-x-z]"), "#D2");
316 Assert.IsTrue (Regex.IsMatch (" \tz-", @"[\s-z]{4}"), "#E1");
317 Assert.IsFalse (Regex.IsMatch ("abcdefghijklmnopqrstuvwxy", @"[\s-z]"), "#E2");
320 [Test, ExpectedException (typeof (ArgumentException))]
321 public void HangingHyphen1 ()
323 Regex.IsMatch ("foobar", @"[a-\s]");
327 public void Bug313642 ()
329 Regex r = new Regex ("(?<a>c)");
330 Match m = r.Match ("a");
331 Assert.AreEqual (1, m.Groups.Count, "#1");
332 Assert.AreEqual (0, m.Groups [0].Captures.Count, "#2");
333 Assert.AreEqual (0, m.Groups [0].Index, "#3");
334 Assert.AreEqual (0, m.Groups [0].Length, "#4");
335 Assert.IsFalse (m.Groups [0].Success, "#5");
336 Assert.AreEqual (string.Empty, m.Groups [0].Value, "#6");
340 public void Bug77487 ()
342 Assert.IsTrue (Regex.IsMatch ("a a", "^(a[^a]*)*a$"), "#1");
343 Assert.IsTrue (Regex.IsMatch ("a a", "^(a *)*a$"), "#2");
344 Assert.IsTrue (Regex.IsMatch ("a a", "(a[^a]*)+a"), "#3");
345 Assert.IsTrue (Regex.IsMatch ("a a", "(a *)+a"), "#4");
349 public void Bug69269 ()
351 string s = "CREATE aa\faa; CREATE bb\nbb; CREATE cc\rcc; CREATE dd\tdd; CREATE ee\vee;";
352 Assert.AreEqual (5, Regex.Matches(s, @"CREATE[\s\S]+?;").Count, "#1");
353 Assert.AreEqual (5, Regex.Matches (s, @"CREATE[ \f\n\r\t\v\S]+?;").Count, "#2");
357 public void Bug76345 ()
360 string s1 = "'asdf'";
361 string s2 = "'as,'df'";
363 m = new Regex("'.*?'").Match(s1);
364 Assert.IsTrue (m.Success, "#A1");
365 Assert.AreEqual (s1, m.Value, "#A2");
367 m = new Regex("'[^,].*?'").Match(s1);
368 Assert.IsTrue (m.Success, "#B1");
369 Assert.AreEqual (s1, m.Value, "#B2");
371 m = new Regex("'.*?[^,]'").Match(s1);
372 Assert.IsTrue (m.Success, "#C1");
373 Assert.AreEqual (s1, m.Value, "#C2");
375 m = new Regex("'.*?[^,]'").Match(s2);
376 Assert.IsTrue (m.Success, "#D1");
377 Assert.AreEqual (s2, m.Value, "#D2");
381 public void Bug78007 ()
383 string test = "head><html>";
384 string pattern = @"\Ahead>\<html\>";
385 Regex r = new Regex (pattern);
386 Match m = r.Match (test);
387 Assert.IsTrue (m.Success, "#A1");
388 Assert.AreEqual (0, m.Index, "#A2");
389 Assert.AreEqual (14, m.Length, "#A3");
392 Assert.IsFalse (m.Success, "#B");
396 public void Bug439947 ()
399 r = new Regex ("(?<=^|/)[^/]*\\.cs$", RegexOptions.None);
400 Assert.IsTrue (r.IsMatch ("z/text2.cs"));
402 r = new Regex ("(?<=^|/)[^/]*\\.cs$", RegexOptions.Compiled);
403 Assert.IsTrue (r.IsMatch ("z/text2.cs"));
407 public void bug443841 ()
409 string numberString = @"[0-9]+";
410 string doubleString = string.Format (@" *[+-]? *{0}(\.{0})?([eE][+-]?{0})? *",
412 string vector1To3String = string.Format (@"{0}(,{0}(,{0})?)?",
415 MatchCollection matches;
417 r = new Regex (string.Format ("^{0}$", vector1To3String));
418 Assert.IsTrue (r.IsMatch ("1"), "#A1");
419 matches = r.Matches ("1");
420 Assert.AreEqual (1, matches.Count, "#A2");
421 Assert.AreEqual ("1", matches [0].Value, "#A3");
423 r = new Regex (string.Format ("^{0}$", vector1To3String),
424 RegexOptions.Compiled);
425 Assert.IsTrue (r.IsMatch ("1"), "#B1");
426 matches = r.Matches ("1");
427 Assert.AreEqual (1, matches.Count, "#B2");
428 Assert.AreEqual ("1", matches [0].Value, "#B3");
432 public void CharClassWithIgnoreCase ()
434 string str = "Foobar qux";
435 Regex re = new Regex (@"[a-z\s]*", RegexOptions.IgnoreCase);
436 Match m = re.Match (str);
437 Assert.AreEqual (str, m.Value);
441 public void No65535Limit ()
445 Kill65535_1 (131071);
446 Kill65535_1 (131072);
450 Kill65535_2 (131066);
451 Kill65535_2 (131067);
455 public void GroupNumbers ()
457 GroupNumbers_1 ("a", 1);
458 GroupNumbers_1 ("(a)", 2);
459 GroupNumbers_1 ("(a)(b)", 3);
460 GroupNumbers_1 ("(a)|(b)", 3);
461 GroupNumbers_1 ("((a)(b))(c)", 5);
465 public void Trials ()
467 foreach (RegexTrial trial in trials)
472 public void Bug80554_0 ()
474 bug80554_trials [0].Execute ();
478 public void Bug80554_1 ()
480 bug80554_trials [1].Execute ();
484 public void Bug80554_2 ()
486 bug80554_trials [2].Execute ();
490 public void Bug80554_3 ()
492 bug80554_trials [3].Execute ();
496 public void Bug432172 ()
498 new Regex ("^(else|elif|except|finally)([^a-zA-Z_0-9]).*", RegexOptions.Compiled);
503 public void Bug610587_RepetitionOfPositionAssertion ()
505 Assert.AreEqual ("888", Regex.Match("888", "^*8.*").Value);
508 void Kill65535_1 (int length)
510 StringBuilder sb = new StringBuilder ("x");
511 sb.Append ('a', length);
513 string teststring = sb.ToString ();
514 Regex regex = new Regex (@"xa*y");
515 Match m = regex.Match (teststring);
516 Assert.IsTrue (m.Success, "#1:" + length);
517 Assert.AreEqual (0, m.Index, "#2:" + length);
518 Assert.AreEqual (teststring.Length, m.Length, "#3:" + length);
521 void Kill65535_2 (int length)
523 StringBuilder sb = new StringBuilder ("xaaaax");
524 sb.Append ('a', length);
526 string teststring = sb.ToString ();
527 Regex regex = new Regex (@"x.*y");
528 Match m = regex.Match(teststring);
529 Assert.IsTrue (m.Success, "#1:" + length);
530 Assert.AreEqual (0, m.Index, "#2:" + length);
531 Assert.AreEqual (teststring.Length, m.Length, "#3:" + length);
534 void GroupNumbers_1 (string s, int n)
536 Regex r = new Regex (s);
537 int [] grps = r.GetGroupNumbers ();
538 Assert.AreEqual (n, grps.Length, "#1:" + r);
541 for (int i = 0; i < grps.Length; ++i) {
543 // group numbers are unique
544 for (int j = 0; j < i; ++j)
545 Assert.IsTrue (grps [i] != grps [j], "#2:" + r + " (" + i + "," + j + ")");
547 // no gaps in group numbering
548 Assert.AreEqual ((n * (n - 1)) / 2, sum, "#3:" + r);
552 static string bug80554_s = @"(?(static)|(.*))(static)";
553 static RegexTrial[] bug80554_trials = {
554 new RegexTrial (bug80554_s, RegexOptions.None, "static", "Pass. Group[0]=(0,6) Group[1]= Group[2]=(0,6)"),
555 new RegexTrial (bug80554_s, RegexOptions.None, "hydrostatic", "Pass. Group[0]=(0,11) Group[1]=(0,5) Group[2]=(5,6)"),
556 new RegexTrial (bug80554_s, RegexOptions.None, "statics", "Pass. Group[0]=(0,6) Group[1]= Group[2]=(0,6)"),
557 new RegexTrial (bug80554_s, RegexOptions.None, "dynamic", "Fail.")
560 static RegexTrial[] trials = {
561 new RegexTrial (@"^[^.\d]*(\d+)(?:\D+(\d+))?", RegexOptions.None, "MD 9.18", "Pass. Group[0]=(0,7) Group[1]=(3,1) Group[2]=(5,2)"),
562 new RegexTrial (@"(.*:|.*)(DirName)", RegexOptions.Compiled, "/home/homedir/DirName", "Pass. Group[0]=(0,21) Group[1]=(0,14) Group[2]=(14,7)")