public async Task Count_Timeout_ThrowsAfterTooLongExecution(RegexEngine engine) { if (RegexHelpers.IsNonBacktracking(engine)) { // Test relies on backtracking taking a long time return; } const string Pattern = @"^(\w+\s?)*$"; const string Input = "An input string that takes a very very very very very very very very very very very long time!"; Regex r = await RegexHelpers.GetRegexAsync(engine, Pattern, RegexOptions.None, TimeSpan.FromMilliseconds(1)); Stopwatch sw = Stopwatch.StartNew(); Assert.Throws <RegexMatchTimeoutException>(() => r.Count(Input)); Assert.Throws <RegexMatchTimeoutException>(() => r.Count(Input.AsSpan())); Assert.InRange(sw.Elapsed.TotalSeconds, 0, 10); // arbitrary upper bound that should be well above what's needed with a 1ms timeout switch (engine) { case RegexEngine.Interpreter: case RegexEngine.Compiled: sw = Stopwatch.StartNew(); Assert.Throws <RegexMatchTimeoutException>(() => Regex.Count(Input, Pattern, RegexHelpers.OptionsFromEngine(engine), TimeSpan.FromMilliseconds(1))); Assert.Throws <RegexMatchTimeoutException>(() => Regex.Count(Input.AsSpan(), Pattern, RegexHelpers.OptionsFromEngine(engine), TimeSpan.FromMilliseconds(1))); Assert.InRange(sw.Elapsed.TotalSeconds, 0, 10); // arbitrary upper bound that should be well above what's needed with a 1ms timeout break; } }
public async Task SingleExpected(RegexEngine engine, char c) { string s = $@"\u{(int)c:X4}"; var set = new HashSet <char>() { c }; // One await ValidateSetAsync(engine, $"{s}", RegexOptions.None, set, null); await ValidateSetAsync(engine, $"[{s}]", RegexOptions.None, set, null); await ValidateSetAsync(engine, $"[^{s}]", RegexOptions.None, null, set); if (!RegexHelpers.IsNonBacktracking(engine)) { // Positive lookahead await ValidateSetAsync(engine, $"(?={s}){s}", RegexOptions.None, set, null); await ValidateSetAsync(engine, $"(?=[^{s}])[^{s}]", RegexOptions.None, null, set); // Negative lookahead await ValidateSetAsync(engine, $"(?![^{s}]){s}", RegexOptions.None, set, null); await ValidateSetAsync(engine, $"(?![{s}])[^{s}]", RegexOptions.None, null, set); } // Concatenation await ValidateSetAsync(engine, $"[{s}{s}]", RegexOptions.None, set, null); await ValidateSetAsync(engine, $"[^{s}{s}{s}]", RegexOptions.None, null, set); // Alternation await ValidateSetAsync(engine, $"{s}|{s}", RegexOptions.None, set, null); await ValidateSetAsync(engine, $"[^{s}]|[^{s}]|[^{s}]", RegexOptions.None, null, set); await ValidateSetAsync(engine, $"{s}|[^{s}]", RegexOptions.None, null, new HashSet <char>()); }
public static IEnumerable <object[]> Count_ReturnsExpectedCount_TestData() { foreach (RegexEngine engine in RegexHelpers.AvailableEngines) { yield return(new object[] { engine, @"", "", 0, RegexOptions.None, 1 }); yield return(new object[] { engine, @"", "a", 0, RegexOptions.None, 2 }); yield return(new object[] { engine, @"", "ab", 0, RegexOptions.None, 3 }); yield return(new object[] { engine, @"", "ab", 1, RegexOptions.None, 2 }); yield return(new object[] { engine, @"\w", "", 0, RegexOptions.None, 0 }); yield return(new object[] { engine, @"\w", "a", 0, RegexOptions.None, 1 }); yield return(new object[] { engine, @"\w", "ab", 0, RegexOptions.None, 2 }); yield return(new object[] { engine, @"\w", "ab", 1, RegexOptions.None, 1 }); yield return(new object[] { engine, @"\w", "ab", 2, RegexOptions.None, 0 }); yield return(new object[] { engine, @"\b\w+\b", "abc def ghi jkl", 0, RegexOptions.None, 4 }); yield return(new object[] { engine, @"\b\w+\b", "abc def ghi jkl", 7, RegexOptions.None, 2 }); yield return(new object[] { engine, @"A", "", 0, RegexOptions.IgnoreCase, 0 }); yield return(new object[] { engine, @"A", "a", 0, RegexOptions.IgnoreCase, 1 }); yield return(new object[] { engine, @"A", "aAaA", 0, RegexOptions.IgnoreCase, 4 }); yield return(new object[] { engine, @".", "\n\n\n", 0, RegexOptions.None, 0 }); yield return(new object[] { engine, @".", "\n\n\n", 0, RegexOptions.Singleline, 3 }); yield return(new object[] { engine, @"[а-я-[аeиоуыэюя]]", "спокойной ночи", 0, RegexOptions.None, 8 }); if (!RegexHelpers.IsNonBacktracking(engine)) { // Lookbehinds yield return(new object[] { engine, @"(?<=abc)\w", "abcxabcy", 7, RegexOptions.None, 1 }); // Starting anchors yield return(new object[] { engine, @"\Gdef", "abcdef", 0, RegexOptions.None, 0 }); yield return(new object[] { engine, @"\Gdef", "abcdef", 3, RegexOptions.None, 1 }); // RightToLeft yield return(new object[] { engine, @"\b\w+\b", "abc def ghi jkl", 15, RegexOptions.RightToLeft, 4 }); yield return(new object[] { RegexEngine.Interpreter, @"(?<=abc)\w", "abcxabcy", 8, RegexOptions.RightToLeft, 2 }); yield return(new object[] { engine, @"(?<=abc)\w", "abcxabcy", 7, RegexOptions.RightToLeft, 1 }); } } }
public static IEnumerable <object[]> TurkishCulture_MatchesWordChar_MemberData() { foreach (RegexEngine engine in RegexHelpers.AvailableEngines) { yield return(new object[] { engine, "I\u0131\u0130i", RegexOptions.None, "I\u0131\u0130i" }); yield return(new object[] { engine, "I\u0131\u0130i", RegexOptions.IgnoreCase, "I\u0131\u0130i" }); if (!RegexHelpers.IsNonBacktracking(engine)) { yield return(new object[] { engine, "I\u0131\u0130i", RegexOptions.IgnoreCase | RegexOptions.ECMAScript, "" }); } } }
public static IEnumerable <object[]> Replace_MatchEvaluator_TestData() { foreach (RegexEngine engine in RegexHelpers.AvailableEngines) { yield return(new object[] { engine, "a", "bbbb", new MatchEvaluator(match => "uhoh"), RegexOptions.None, 4, 0, "bbbb" }); yield return(new object[] { engine, "(Big|Small)", "Big mountain", new MatchEvaluator(MatchEvaluator1), RegexOptions.None, 12, 0, "Huge mountain" }); yield return(new object[] { engine, "(Big|Small)", "Small village", new MatchEvaluator(MatchEvaluator1), RegexOptions.None, 13, 0, "Tiny village" }); if ("i".ToUpper() == "I") { yield return(new object[] { engine, "(Big|Small)", "bIG horse", new MatchEvaluator(MatchEvaluator1), RegexOptions.IgnoreCase, 9, 0, "Huge horse" }); } yield return(new object[] { engine, "(Big|Small)", "sMaLl dog", new MatchEvaluator(MatchEvaluator1), RegexOptions.IgnoreCase, 9, 0, "Tiny dog" }); yield return(new object[] { engine, ".+", "XSP_TEST_FAILURE", new MatchEvaluator(MatchEvaluator2), RegexOptions.None, 16, 0, "SUCCESS" }); yield return(new object[] { engine, "[abcabc]", "abcabc", new MatchEvaluator(MatchEvaluator3), RegexOptions.None, 6, 0, "ABCABC" }); yield return(new object[] { engine, "[abcabc]", "abcabc", new MatchEvaluator(MatchEvaluator3), RegexOptions.None, 3, 0, "ABCabc" }); yield return(new object[] { engine, "[abcabc]", "abcabc", new MatchEvaluator(MatchEvaluator3), RegexOptions.None, 3, 2, "abCABc" }); if (!RegexHelpers.IsNonBacktracking(engine)) { // Regression test: // Regex treating Devanagari matra characters as matching "\b" // Unicode characters in the "Mark, NonSpacing" Category, U+0902=Devanagari sign anusvara, U+0947=Devanagri vowel sign E string boldInput = "\u092f\u0939 \u0915\u0930 \u0935\u0939 \u0915\u0930\u0947\u0902 \u0939\u0948\u0964"; string boldExpected = "\u092f\u0939 <b>\u0915\u0930</b> \u0935\u0939 <b>\u0915\u0930\u0947\u0902</b> \u0939\u0948\u0964"; yield return(new object[] { engine, @"\u0915\u0930.*?\b", boldInput, new MatchEvaluator(MatchEvaluatorBold), RegexOptions.CultureInvariant | RegexOptions.Singleline, boldInput.Length, 0, boldExpected }); // RighToLeft yield return(new object[] { engine, "a", "bbbb", new MatchEvaluator(match => "uhoh"), RegexOptions.RightToLeft, 4, 3, "bbbb" }); yield return(new object[] { engine, @"foo\s+", "0123456789foo4567890foo ", new MatchEvaluator(MatchEvaluatorBar), RegexOptions.RightToLeft, 32, 32, "0123456789foo4567890bar" }); yield return(new object[] { engine, @"\d", "0123456789foo4567890foo ", new MatchEvaluator(MatchEvaluatorPoundSign), RegexOptions.RightToLeft, 17, 32, "##########foo#######foo " }); yield return(new object[] { engine, @"\d", "0123456789foo4567890foo ", new MatchEvaluator(MatchEvaluatorPoundSign), RegexOptions.RightToLeft, 7, 32, "0123456789foo#######foo " }); yield return(new object[] { engine, @"\d", "0123456789foo4567890foo ", new MatchEvaluator(MatchEvaluatorPoundSign), RegexOptions.RightToLeft, 0, 32, "0123456789foo4567890foo " }); yield return(new object[] { engine, @"\d", "0123456789foo4567890foo ", new MatchEvaluator(MatchEvaluatorPoundSign), RegexOptions.RightToLeft, -1, 32, "##########foo#######foo " }); } } }
public async Task Matches_MultipleCapturingGroups(RegexEngine engine) { string[] expectedGroupValues = { "abracadabra", "abra", "cad" }; string[] expectedGroupCaptureValues = { "abracad", "abra" }; // Another example - given by Brad Merril in an article on RegularExpressions Regex regex = await RegexHelpers.GetRegexAsync(engine, @"(abra(cad)?)+"); string input = "abracadabra1abracadabra2abracadabra3"; Match match = regex.Match(input); while (match.Success) { string expected = "abracadabra"; RegexAssert.Equal(expected, match); if (!RegexHelpers.IsNonBacktracking(engine)) { Assert.Equal(3, match.Groups.Count); for (int i = 0; i < match.Groups.Count; i++) { RegexAssert.Equal(expectedGroupValues[i], match.Groups[i]); if (i == 1) { Assert.Equal(2, match.Groups[i].Captures.Count); for (int j = 0; j < match.Groups[i].Captures.Count; j++) { RegexAssert.Equal(expectedGroupCaptureValues[j], match.Groups[i].Captures[j]); } } else if (i == 2) { Assert.Equal(1, match.Groups[i].Captures.Count); RegexAssert.Equal("cad", match.Groups[i].Captures[0]); } } Assert.Equal(1, match.Captures.Count); RegexAssert.Equal("abracadabra", match.Captures[0]); } match = match.NextMatch(); } }
public void EnumerateMatches_Lookbehind(RegexEngine engine) { if (RegexHelpers.IsNonBacktracking(engine)) { // lookbehinds not supported return; } const string Pattern = @"(?<=\b20)\d{2}\b"; const string Input = "2010 1999 1861 2140 2009"; Regex r = RegexHelpers.GetRegexAsync(engine, Pattern, RegexOptions.IgnoreCase).GetAwaiter().GetResult(); int count = 0; string[] expectedMatches = new[] { "10", "09" }; ReadOnlySpan <char> span = Input.AsSpan(); foreach (ValueMatch match in r.EnumerateMatches(span)) { Assert.Equal(expectedMatches[count++], span.Slice(match.Index, match.Length).ToString()); } Assert.Equal(2, count); }
public void EnumerateMatches_Lookahead(RegexEngine engine) { if (RegexHelpers.IsNonBacktracking(engine)) { // lookaheads not supported return; } const string Pattern = @"\b(?!un)\w+\b"; const string Input = "unite one unethical ethics use untie ultimate"; Regex r = RegexHelpers.GetRegexAsync(engine, Pattern, RegexOptions.IgnoreCase).GetAwaiter().GetResult(); int count = 0; string[] expectedMatches = new[] { "one", "ethics", "use", "ultimate" }; ReadOnlySpan <char> span = Input.AsSpan(); foreach (ValueMatch match in r.EnumerateMatches(span)) { Assert.Equal(expectedMatches[count++], span.Slice(match.Index, match.Length).ToString()); } Assert.Equal(4, count); }
public static IEnumerable <object[]> Replace_String_TestData() { foreach (RegexEngine engine in RegexHelpers.AvailableEngines) { yield return(new object[] { engine, @"a", "bbbb", "c", RegexOptions.None, 4, 3, "bbbb" }); yield return(new object[] { engine, @"", " ", "123", RegexOptions.None, 4, 0, "123 123 123 123" }); yield return(new object[] { engine, "icrosoft", "MiCrOsOfT", "icrosoft", RegexOptions.IgnoreCase, 9, 0, "Microsoft" }); yield return(new object[] { engine, "dog", "my dog has fleas", "CAT", RegexOptions.IgnoreCase, 16, 0, "my CAT has fleas" }); yield return(new object[] { engine, "a", "aaaaa", "b", RegexOptions.None, 2, 0, "bbaaa" }); yield return(new object[] { engine, "a", "aaaaa", "b", RegexOptions.None, 2, 3, "aaabb" }); // Stress yield return(new object[] { engine, ".", new string('a', 1000), "b", RegexOptions.None, 1000, 0, new string('b', 1000) }); // Undefined groups yield return(new object[] { engine, @"(?<256>cat)\s*(?<512>dog)", "slkfjsdcat dogkljeah", "STARTcat$2048$1024dogEND", RegexOptions.None, 20, 0, "slkfjsdSTARTcat$2048$1024dogENDkljeah" }); yield return(new object[] { engine, @"(?<cat>cat)\s*(?<dog>dog)", "slkfjsdcat dogkljeah", "START${catTWO}dogcat${dogTWO}END", RegexOptions.None, 20, 0, "slkfjsdSTART${catTWO}dogcat${dogTWO}ENDkljeah" }); // Replace with group numbers yield return(new object[] { engine, "([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z])))))))))))))))", "abcdefghiklmnop", "$15", RegexOptions.None, 15, 0, "p" }); yield return(new object[] { engine, "([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z]([a-z])))))))))))))))", "abcdefghiklmnop", "$3", RegexOptions.None, 15, 0, "cdefghiklmnop" }); yield return(new object[] { engine, @"D\.(.+)", "D.Bau", "David $1", RegexOptions.None, 5, 0, "David Bau" }); // Stress string pattern = string.Concat(Enumerable.Repeat("([a-z]", 1000).Concat(Enumerable.Repeat(")", 1000))); string input = string.Concat(Enumerable.Repeat("abcde", 200)); yield return(new object[] { engine, pattern, input, "$1000", RegexOptions.None, input.Length, 0, "e" }); yield return(new object[] { engine, pattern, input, "$1", RegexOptions.None, input.Length, 0, input }); // Undefined group yield return(new object[] { engine, "([a_z])(.+)", "abc", "$3", RegexOptions.None, 3, 0, "$3" }); yield return(new object[] { engine, @"(?<256>cat)\s*(?<512>dog)", "slkfjsdcat dogkljeah", "STARTcat$2048$1024dogEND", RegexOptions.None, 20, 0, "slkfjsdSTARTcat$2048$1024dogENDkljeah" }); // Valid cases yield return(new object[] { engine, @"[^ ]+\s(?<time>)", "08/10/99 16:00", "${time}", RegexOptions.None, 14, 0, "16:00" }); yield return(new object[] { engine, @"(?<cat>cat)\s*(?<dog>dog)", "cat dog", "${cat}est ${dog}est", RegexOptions.None, 7, 0, "catest dogest" }); yield return(new object[] { engine, @"(?<cat>cat)\s*(?<dog>dog)", "slkfjsdcat dogkljeah", "START${cat}dogcat${dog}END", RegexOptions.None, 20, 0, "slkfjsdSTARTcatdogcatdogENDkljeah" }); yield return(new object[] { engine, @"(?<512>cat)\s*(?<256>dog)", "slkfjsdcat dogkljeah", "START${512}dogcat${256}END", RegexOptions.None, 20, 0, "slkfjsdSTARTcatdogcatdogENDkljeah" }); yield return(new object[] { engine, @"(?<256>cat)\s*(?<512>dog)", "slkfjsdcat dogkljeah", "START${256}dogcat${512}END", RegexOptions.None, 20, 0, "slkfjsdSTARTcatdogcatdogENDkljeah" }); yield return(new object[] { engine, @"(?<512>cat)\s*(?<256>dog)", "slkfjsdcat dogkljeah", "STARTcat$256$512dogEND", RegexOptions.None, 20, 0, "slkfjsdSTARTcatdogcatdogENDkljeah" }); yield return(new object[] { engine, @"(?<256>cat)\s*(?<512>dog)", "slkfjsdcat dogkljeah", "STARTcat$512$256dogEND", RegexOptions.None, 20, 0, "slkfjsdSTARTcatdogcatdogENDkljeah" }); yield return(new object[] { engine, @"(hello)cat\s+dog(world)", "hellocat dogworld", "$1$$$2", RegexOptions.None, 19, 0, "hello$world" }); yield return(new object[] { engine, @"(cat)\s+(dog)", "before textcat dogafter text", ". The following should be dog and it is $+. ", RegexOptions.None, 28, 0, "before text. The following should be dog and it is dog. after text" }); yield return(new object[] { engine, @"(hello)\s+(world)", "What the hello world goodby", "$&, how are you?", RegexOptions.None, 27, 0, "What the hello world, how are you? goodby" }); yield return(new object[] { engine, @"(hello)\s+(world)", "What the hello world goodby", "$0, how are you?", RegexOptions.None, 27, 0, "What the hello world, how are you? goodby" }); yield return(new object[] { engine, @"(hello)\s+(world)", "What the hello world goodby", "$`cookie are you doing", RegexOptions.None, 27, 0, "What the What the cookie are you doing goodby" }); yield return(new object[] { engine, @"(cat)\s+(dog)", "before textcat dogafter text", ". This is the $' and ", RegexOptions.None, 28, 0, "before text. This is the after text and after text" }); yield return(new object[] { engine, @"(cat)\s+(dog)", "before textcat dogafter text", ". The following should be the entire string '$_'. ", RegexOptions.None, 28, 0, "before text. The following should be the entire string 'before textcat dogafter text'. after text" }); yield return(new object[] { engine, @"(hello)\s+(world)", "START hello world END", "$2 $1 $1 $2 $3$4", RegexOptions.None, 24, 0, "START world hello hello world $3$4 END" }); yield return(new object[] { engine, @"(hello)\s+(world)", "START hello world END", "$2 $1 $1 $2 $123$234", RegexOptions.None, 24, 0, "START world hello hello world $123$234 END" }); yield return(new object[] { engine, @"(d)(o)(g)(\s)(c)(a)(t)(\s)(h)(a)(s)", "My dog cat has fleas.", "$01$02$03$04$05$06$07$08$09$10$11", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Multiline, 21, 0, "My dog cat has fleas." }); yield return(new object[] { engine, @"(d)(o)(g)(\s)(c)(a)(t)(\s)(h)(a)(s)", "My dog cat has fleas.", "$05$06$07$04$01$02$03$08$09$10$11", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Multiline, 21, 0, "My cat dog has fleas." }); // Error cases yield return(new object[] { engine, @"(?<256>cat)\s*(?<512>dog)", "slkfjsdcat dogkljeah", "STARTcat$512$", RegexOptions.None, 20, 0, "slkfjsdSTARTcatdog$kljeah" }); if (!RegexHelpers.IsNonBacktracking(engine)) { // ECMAScript yield return(new object[] { engine, @"(?<512>cat)\s*(?<256>dog)", "slkfjsdcat dogkljeah", "STARTcat${256}${512}dogEND", RegexOptions.ECMAScript, 20, 0, "slkfjsdSTARTcatdogcatdogENDkljeah" }); yield return(new object[] { engine, @"(?<256>cat)\s*(?<512>dog)", "slkfjsdcat dogkljeah", "STARTcat${512}${256}dogEND", RegexOptions.ECMAScript, 20, 0, "slkfjsdSTARTcatdogcatdogENDkljeah" }); yield return(new object[] { engine, @"(?<1>cat)\s*(?<2>dog)", "slkfjsdcat dogkljeah", "STARTcat$2$1dogEND", RegexOptions.ECMAScript, 20, 0, "slkfjsdSTARTcatdogcatdogENDkljeah" }); yield return(new object[] { engine, @"(?<2>cat)\s*(?<1>dog)", "slkfjsdcat dogkljeah", "STARTcat$1$2dogEND", RegexOptions.ECMAScript, 20, 0, "slkfjsdSTARTcatdogcatdogENDkljeah" }); yield return(new object[] { engine, @"(?<512>cat)\s*(?<256>dog)", "slkfjsdcat dogkljeah", "STARTcat$256$512dogEND", RegexOptions.ECMAScript, 20, 0, "slkfjsdSTARTcatdogcatdogENDkljeah" }); yield return(new object[] { engine, @"(?<256>cat)\s*(?<512>dog)", "slkfjsdcat dogkljeah", "START${256}dogcat${512}END", RegexOptions.ECMAScript, 20, 0, "slkfjsdSTARTcatdogcatdogENDkljeah" }); yield return(new object[] { engine, @"(hello)\s+world", "START hello world END", "$234 $1 $1 $234 $3$4", RegexOptions.ECMAScript, 24, 0, "START $234 hello hello $234 $3$4 END" }); yield return(new object[] { engine, @"(hello)\s+(world)", "START hello world END", "$2 $1 $1 $2 $3$4", RegexOptions.ECMAScript, 24, 0, "START world hello hello world $3$4 END" }); yield return(new object[] { engine, @"(hello)\s+(world)", "START hello world END", "$2 $1 $1 $2 $123$234", RegexOptions.ECMAScript, 24, 0, "START world hello hello world hello23world34 END" }); yield return(new object[] { engine, @"(?<12>hello)\s+(world)", "START hello world END", "$1 $12 $12 $1 $123$134", RegexOptions.ECMAScript, 24, 0, "START world hello hello world hello3world34 END" }); yield return(new object[] { engine, @"(?<123>hello)\s+(?<23>world)", "START hello world END", "$23 $123 $123 $23 $123$234", RegexOptions.ECMAScript, 24, 0, "START world hello hello world helloworld4 END" }); yield return(new object[] { engine, @"(?<123>hello)\s+(?<234>world)", "START hello world END", "$234 $123 $123 $234 $123456$234567", RegexOptions.ECMAScript, 24, 0, "START world hello hello world hello456world567 END" }); yield return(new object[] { engine, @"(d)(o)(g)(\s)(c)(a)(t)(\s)(h)(a)(s)", "My dog cat has fleas.", "$01$02$03$04$05$06$07$08$09$10$11", RegexOptions.CultureInvariant | RegexOptions.ECMAScript | RegexOptions.IgnoreCase | RegexOptions.Multiline, 21, 0, "My dog cat has fleas." }); yield return(new object[] { engine, @"(d)(o)(g)(\s)(c)(a)(t)(\s)(h)(a)(s)", "My dog cat has fleas.", "$05$06$07$04$01$02$03$08$09$10$11", RegexOptions.CultureInvariant | RegexOptions.ECMAScript | RegexOptions.IgnoreCase | RegexOptions.Multiline, 21, 0, "My cat dog has fleas." }); // RightToLeft yield return(new object[] { engine, @"a", "bbbb", "c", RegexOptions.RightToLeft, 4, 3, "bbbb" }); yield return(new object[] { engine, @"", " ", "123", RegexOptions.RightToLeft, 4, 3, "123 123 123 123" }); yield return(new object[] { engine, @"foo\s+", "0123456789foo4567890foo ", "bar", RegexOptions.RightToLeft, 32, 32, "0123456789foo4567890bar" }); yield return(new object[] { engine, @"\d", "0123456789foo4567890foo ", "#", RegexOptions.RightToLeft, 17, 32, "##########foo#######foo " }); yield return(new object[] { engine, @"\d", "0123456789foo4567890foo ", "#", RegexOptions.RightToLeft, 7, 32, "0123456789foo#######foo " }); yield return(new object[] { engine, @"\d", "0123456789foo4567890foo ", "#", RegexOptions.RightToLeft, 0, 32, "0123456789foo4567890foo " }); yield return(new object[] { engine, @"\d", "0123456789foo4567890foo ", "#", RegexOptions.RightToLeft, -1, 32, "##########foo#######foo " }); yield return(new object[] { engine, "([1-9])([1-9])([1-9])def", "abc123def!", "$0", RegexOptions.RightToLeft, -1, 10, "abc123def!" }); yield return(new object[] { engine, "([1-9])([1-9])([1-9])def", "abc123def!", "$1", RegexOptions.RightToLeft, -1, 10, "abc1!" }); yield return(new object[] { engine, "([1-9])([1-9])([1-9])def", "abc123def!", "$2", RegexOptions.RightToLeft, -1, 10, "abc2!" }); yield return(new object[] { engine, "([1-9])([1-9])([1-9])def", "abc123def!", "$3", RegexOptions.RightToLeft, -1, 10, "abc3!" }); yield return(new object[] { engine, "([1-9])([1-9])([1-9])def", "abc123def!", "$4", RegexOptions.RightToLeft, -1, 10, "abc$4!" }); yield return(new object[] { engine, "([1-9])([1-9])([1-9])def", "abc123def!", "$$", RegexOptions.RightToLeft, -1, 10, "abc$!" }); yield return(new object[] { engine, "([1-9])([1-9])([1-9])def", "abc123def!", "$&", RegexOptions.RightToLeft, -1, 10, "abc123def!" }); yield return(new object[] { engine, "([1-9])([1-9])([1-9])def", "abc123def!", "$`", RegexOptions.RightToLeft, -1, 10, "abcabc!" }); yield return(new object[] { engine, "([1-9])([1-9])([1-9])def", "abc123def!", "$'", RegexOptions.RightToLeft, -1, 10, "abc!!" }); yield return(new object[] { engine, "([1-9])([1-9])([1-9])def", "abc123def!", "$+", RegexOptions.RightToLeft, -1, 10, "abc3!" }); yield return(new object[] { engine, "([1-9])([1-9])([1-9])def", "abc123def!", "$_", RegexOptions.RightToLeft, -1, 10, "abcabc123def!!" }); // Anchors yield return(new object[] { engine, @"\Ga", "aaaaa", "b", RegexOptions.None, 5, 0, "bbbbb" }); } } }
public static IEnumerable <object[]> Match_In_Different_Cultures_TestData() { CultureInfo invariant = CultureInfo.InvariantCulture; CultureInfo enUS = new CultureInfo("en-US"); CultureInfo turkish = new CultureInfo("tr-TR"); foreach (RegexEngine engine in RegexHelpers.AvailableEngines) { foreach (RegexOptions option in new[] { RegexOptions.None, RegexOptions.RightToLeft }) { if (RegexHelpers.IsNonBacktracking(engine) && (option & RegexOptions.RightToLeft) != 0) { continue; } // \u0130 (Turkish I with dot) and \u0131 (Turkish i without dot) are unrelated characters in general // Expected answers in the default en-US culture yield return(new object[] { "(?i:I)", option, engine, enUS, "xy\u0131ab", "" }); yield return(new object[] { "(?i:iI+)", option, engine, enUS, "abcIIIxyz", "III" }); yield return(new object[] { "(?i:iI+)", option, engine, enUS, "abcIi\u0130xyz", "Ii\u0130" }); yield return(new object[] { "(?i:iI+)", option, engine, enUS, "abcI\u0130ixyz", "I\u0130i" }); yield return(new object[] { "(?i:iI+)", option, engine, enUS, "abc\u0130IIxyz", "\u0130II" }); yield return(new object[] { "(?i:iI+)", option, engine, enUS, "abc\u0130\u0131Ixyz", "" }); yield return(new object[] { "(?i:iI+)", option, engine, enUS, "abc\u0130Iixyz", "\u0130Ii" }); yield return(new object[] { "(?i:[^IJKLM]I)", option, engine, enUS, "ii\u0130i\u0131ab", "" }); // Expected answers in the invariant culture yield return(new object[] { "(?i:I)", option, engine, invariant, "xy\u0131ab", "" }); yield return(new object[] { "(?i:iI+)", option, engine, invariant, "abcIIIxyz", "III" }); yield return(new object[] { "(?i:iI+)", option, engine, invariant, "abc\u0130\u0131Ixyz", "" }); // Expected answers in the Turkish culture // // Android produces unexpected results for tr-TR // https://github.com/dotnet/runtime/issues/60568 if (!PlatformDetection.IsAndroid) { yield return(new object[] { "(?i:I)", option, engine, turkish, "xy\u0131ab", "\u0131" }); yield return(new object[] { "(?i:iI+)", option, engine, turkish, "abcIIIxyz", "" }); yield return(new object[] { "(?i:iI+)", option, engine, turkish, "abcIi\u0130xyz", "" }); yield return(new object[] { "(?i:iI+)", option, engine, turkish, "abcI\u0130ixyz", "" }); yield return(new object[] { "(?i:[^IJKLM]I)", option, engine, turkish, "ii\u0130i\u0131ab", "i\u0131" }); yield return(new object[] { "(?i)\u0049", option, engine, turkish, "\u0131", "\u0131" }); yield return(new object[] { "(?i)[a\u0049]", option, engine, turkish, "c\u0131c", "\u0131" }); } } // None and Compiled are separated into the Match_In_Different_Cultures_CriticalCases test if (RegexHelpers.IsNonBacktracking(engine)) { foreach (object[] data in Match_In_Different_Cultures_CriticalCases_TestData_For(engine)) { yield return(data); } } } }
public static IEnumerable <object[]> Split_TestData() { foreach (RegexEngine engine in RegexHelpers.AvailableEngines) { yield return(new object[] { engine, "", "", RegexOptions.None, 0, 0, new string[] { "", "" } }); yield return(new object[] { engine, "123", "abc", RegexOptions.None, 3, 0, new string[] { "abc" } }); yield return(new object[] { engine, " ", "word0 word1 word2 word3", RegexOptions.None, 32, 0, new string[] { "word0", "word1", "word2", "word3" } }); yield return(new object[] { engine, ":", "kkk:lll:mmm:nnn:ooo", RegexOptions.None, 19, 0, new string[] { "kkk", "lll", "mmm", "nnn", "ooo" } }); yield return(new object[] { engine, ":", "kkk:lll:mmm:nnn:ooo", RegexOptions.None, 0, 0, new string[] { "kkk", "lll", "mmm", "nnn", "ooo" } }); // IgnoreCase yield return(new object[] { engine, "[abc]", "1A2B3C4", RegexOptions.IgnoreCase, 7, 0, new string[] { "1", "2", "3", "4" } }); // Custom index yield return(new object[] { engine, ":", "kkk:lll:mmm:nnn:ooo", RegexOptions.None, 2, 0, new string[] { "kkk", "lll:mmm:nnn:ooo" } }); yield return(new object[] { engine, ":", "kkk:lll:mmm:nnn:ooo", RegexOptions.None, 3, 6, new string[] { "kkk:lll", "mmm", "nnn:ooo" } }); // Tricky corner cases involving empty matches of anchors yield return(new object[] { engine, @"\b", "Hello World!", RegexOptions.None, 3, 6, new string[] { "Hello ", "World", "!" } }); yield return(new object[] { engine, @"\b", "Hello World!", RegexOptions.None, 0, 0, new string[] { "", "Hello", " ", "World", "!" } }); yield return(new object[] { engine, @"^", "Hello \nWorld!", RegexOptions.None | RegexOptions.Multiline, 0, 0, new string[] { "", "Hello \n", "World!" } }); yield return(new object[] { engine, @"$", "Hello \nWorld!", RegexOptions.None | RegexOptions.Multiline, 0, 0, new string[] { "Hello ", "\nWorld!", "" } }); yield return(new object[] { engine, @"(\s)?(-)", "once -upon-a time", RegexOptions.None, 17, 0, new string[] { "once", " ", "-", "upon", "-", "a time" } }); yield return(new object[] { engine, @"(\s)?(-)", "once upon a time", RegexOptions.None, 16, 0, new string[] { "once upon a time" } }); yield return(new object[] { engine, @"(\s)?(-)", "once - -upon- a- time", RegexOptions.None, 21, 0, new string[] { "once", " ", "-", "", " ", "-", "upon", "-", " a", "-", " time" } }); yield return(new object[] { engine, "a(.)c(.)e", "123abcde456aBCDe789", RegexOptions.None, 19, 0, new string[] { "123", "b", "d", "456aBCDe789" } }); yield return(new object[] { engine, "a(.)c(.)e", "123abcde456aBCDe789", RegexOptions.IgnoreCase, 19, 0, new string[] { "123", "b", "d", "456", "B", "D", "789" } }); yield return(new object[] { engine, "a(?<dot1>.)c(.)e", "123abcde456aBCDe789", RegexOptions.None, 19, 0, new string[] { "123", "d", "b", "456aBCDe789" } }); yield return(new object[] { engine, "a(?<dot1>.)c(.)e", "123abcde456aBCDe789", RegexOptions.IgnoreCase, 19, 0, new string[] { "123", "d", "b", "456", "D", "B", "789" } }); if (!RegexHelpers.IsNonBacktracking(engine)) { // RightToLeft yield return(new object[] { engine, "", "", RegexOptions.RightToLeft, 0, 0, new string[] { "", "" } }); yield return(new object[] { engine, "123", "abc", RegexOptions.RightToLeft, 3, 0, new string[] { "abc" } }); yield return(new object[] { engine, "a(.)c(.)e", "123abcde456aBCDe789", RegexOptions.RightToLeft, 19, 19, new string[] { "123", "d", "b", "456aBCDe789" } }); yield return(new object[] { engine, "a(.)c(.)e", "123abcde456aBCDe789", RegexOptions.RightToLeft | RegexOptions.IgnoreCase, 19, 19, new string[] { "123", "d", "b", "456", "D", "B", "789" } }); yield return(new object[] { engine, "a(?<dot1>.)c(.)e", "123abcde456aBCDe789", RegexOptions.RightToLeft, 19, 19, new string[] { "123", "b", "d", "456aBCDe789" } }); yield return(new object[] { engine, "a(?<dot1>.)c(.)e", "123abcde456aBCDe789", RegexOptions.RightToLeft | RegexOptions.IgnoreCase, 19, 19, new string[] { "123", "b", "d", "456", "B", "D", "789" } }); yield return(new object[] { engine, "foo", "0123456789foo4567890foo ", RegexOptions.RightToLeft, 32, 32, new string[] { "0123456789", "4567890", " " } }); yield return(new object[] { engine, @"\d", "1a2b3c4d5e6f7g8h9i0k", RegexOptions.RightToLeft, 20, 20, new string[] { "", "a", "b", "c", "d", "e", "f", "g", "h", "i", "k" } }); yield return(new object[] { engine, @"\d", "1a2b3c4d5e6f7g8h9i0k", RegexOptions.RightToLeft, 10, 20, new string[] { "1a", "b", "c", "d", "e", "f", "g", "h", "i", "k" } }); yield return(new object[] { engine, @"\d", "1a2b3c4d5e6f7g8h9i0k", RegexOptions.RightToLeft, 2, 20, new string[] { "1a2b3c4d5e6f7g8h9i", "k" } }); yield return(new object[] { engine, @"\d", "1a2b3c4d5e6f7g8h9i0k", RegexOptions.RightToLeft, 1, 20, new string[] { "1a2b3c4d5e6f7g8h9i0k" } }); // Anchors yield return(new object[] { engine, @"(?<=\G..)(?=..)", "aabbccdd", RegexOptions.None, 8, 0, new string[] { "aa", "bb", "cc", "dd" } }); } } }
public static IEnumerable <object[]> Matches_TestData() { foreach (RegexEngine engine in RegexHelpers.AvailableEngines) { yield return(new object[] { engine, "[0-9]", "12345asdfasdfasdfljkhsda67890", RegexOptions.None, new CaptureData[] { new CaptureData("1", 0, 1), new CaptureData("2", 1, 1), new CaptureData("3", 2, 1), new CaptureData("4", 3, 1), new CaptureData("5", 4, 1), new CaptureData("6", 24, 1), new CaptureData("7", 25, 1), new CaptureData("8", 26, 1), new CaptureData("9", 27, 1), new CaptureData("0", 28, 1), } }); yield return(new object[] { engine, "[a-z0-9]+", "[token1]? GARBAGEtoken2GARBAGE ;token3!", RegexOptions.None, new CaptureData[] { new CaptureData("token1", 1, 6), new CaptureData("token2", 17, 6), new CaptureData("token3", 32, 6) } }); yield return(new object[] { engine, "(abc){2}", " !abcabcasl dkfjasiduf 12343214-//asdfjzpiouxoifzuoxpicvql23r\\` #$3245,2345278 :asdfas & 100% @daeeffga (ryyy27343) poiweurwabcabcasdfalksdhfaiuyoiruqwer{234}/[(132387 + x)]'aaa''?", RegexOptions.None, new CaptureData[] { new CaptureData("abcabc", 2, 6), new CaptureData("abcabc", 125, 6) } }); yield return(new object[] { engine, @"\b\w*\b", "handling words of various lengths", RegexOptions.None, new CaptureData[] { new CaptureData("handling", 0, 8), new CaptureData("", 8, 0), new CaptureData("words", 9, 5), new CaptureData("", 14, 0), new CaptureData("of", 15, 2), new CaptureData("", 17, 0), new CaptureData("various", 18, 7), new CaptureData("", 25, 0), new CaptureData("lengths", 26, 7), new CaptureData("", 33, 0), } }); yield return(new object[] { engine, @"\b\w{2}\b", "handling words of various lengths", RegexOptions.None, new CaptureData[] { new CaptureData("of", 15, 2), } }); yield return(new object[] { engine, @"\w{6,}", "handling words of various lengths", RegexOptions.None, new CaptureData[] { new CaptureData("handling", 0, 8), new CaptureData("various", 18, 7), new CaptureData("lengths", 26, 7), } }); yield return(new object[] { engine, "[a-z]", "a", RegexOptions.None, new CaptureData[] { new CaptureData("a", 0, 1) } }); yield return(new object[] { engine, "[a-z]", "a1bc", RegexOptions.None, new CaptureData[] { new CaptureData("a", 0, 1), new CaptureData("b", 2, 1), new CaptureData("c", 3, 1) } }); yield return(new object[] { engine, "(?:ab|cd|ef|gh|i)j", "abj cdj efj ghjij", RegexOptions.None, new CaptureData[] { new CaptureData("abj", 0, 3), new CaptureData("cdj", 7, 3), new CaptureData("efj", 12, 3), new CaptureData("ghj", 26, 3), new CaptureData("ij", 29, 2), } }); // Using ^ and $ with multiline yield return(new object[] { engine, "^", "", RegexOptions.Multiline, new[] { new CaptureData("", 0, 0) } }); yield return(new object[] { engine, "^", "\n\n\n", RegexOptions.Multiline, new[] { new CaptureData("", 0, 0), new CaptureData("", 1, 0), new CaptureData("", 2, 0), new CaptureData("", 3, 0) } }); yield return(new object[] { engine, "^abc", "abc\nabc \ndef abc \nab\nabc", RegexOptions.Multiline, new[] { new CaptureData("abc", 0, 3), new CaptureData("abc", 4, 3), new CaptureData("abc", 21, 3), } }); yield return(new object[] { engine, @"^\w{5}", "abc\ndefg\n\nhijkl\n", RegexOptions.Multiline, new[] { new CaptureData("hijkl", 10, 5), } }); yield return(new object[] { engine, @"^.*$", "abc\ndefg\n\nhijkl\n", RegexOptions.Multiline, new[] { new CaptureData("abc", 0, 3), new CaptureData("defg", 4, 4), new CaptureData("", 9, 0), new CaptureData("hijkl", 10, 5), new CaptureData("", 16, 0), } }); yield return(new object[] { engine, ".*", "abc", RegexOptions.None, new[] { new CaptureData("abc", 0, 3), new CaptureData("", 3, 0) } }); yield return(new object[] { engine, @"^[^a]a", "bar\n", RegexOptions.Multiline, new[] { new CaptureData("ba", 0, 2) } }); yield return(new object[] { engine, @"^[^a]a", "car\nbar\n", RegexOptions.Multiline, new[] { new CaptureData("ca", 0, 2), new CaptureData("ba", 4, 2) } }); yield return(new object[] { engine, @"[0-9]cat$", "1cat\n2cat", RegexOptions.Multiline, new[] { new CaptureData("1cat", 0, 4), new CaptureData("2cat", 5, 4) } }); if (!PlatformDetection.IsNetFramework) { // .NET Framework missing fix in https://github.com/dotnet/runtime/pull/1075 yield return(new object[] { engine, @"[a -\-\b]", "a #.", RegexOptions.None, new CaptureData[] { new CaptureData("a", 0, 1), new CaptureData(" ", 1, 1), new CaptureData("#", 2, 1), } }); } if (!RegexHelpers.IsNonBacktracking(engine)) { yield return(new object[] { engine, @"foo\d+", "0123456789foo4567890foo1foo 0987", RegexOptions.RightToLeft, new CaptureData[] { new CaptureData("foo1", 20, 4), new CaptureData("foo4567890", 10, 10), } }); yield return(new object[] { engine, "(?(A)A123|C789)", "A123 B456 C789", RegexOptions.None, new CaptureData[] { new CaptureData("A123", 0, 4), new CaptureData("C789", 10, 4), } }); yield return(new object[] { engine, "(?(A)A123|C789)", "A123 B456 C789", RegexOptions.None, new CaptureData[] { new CaptureData("A123", 0, 4), new CaptureData("C789", 10, 4), } }); yield return(new object[] { engine, @"(?(\w+)\w+|)", "abcd", RegexOptions.None, new CaptureData[] { new CaptureData("abcd", 0, 4), new CaptureData("", 4, 0), } }); if (!PlatformDetection.IsNetFramework) { // .NET Framework has some behavioral inconsistencies when there's no else branch. yield return(new object[] { engine, @"(?(\w+)\w+)", "abcd", RegexOptions.None, new CaptureData[] { new CaptureData("abcd", 0, 4), new CaptureData("", 4, 0), } }); } yield return(new object[] { engine, @"^.*$", "abc\ndefg\n\nhijkl\n", RegexOptions.Multiline | RegexOptions.RightToLeft, new[] { new CaptureData("", 16, 0), new CaptureData("hijkl", 10, 5), new CaptureData("", 9, 0), new CaptureData("defg", 4, 4), new CaptureData("abc", 0, 3), } }); if (!PlatformDetection.IsNetFramework) { // .NET Framework missing fix in https://github.com/dotnet/runtime/pull/993 yield return(new object[] { engine, "[^]", "every", RegexOptions.ECMAScript, new CaptureData[] { new CaptureData("e", 0, 1), new CaptureData("v", 1, 1), new CaptureData("e", 2, 1), new CaptureData("r", 3, 1), new CaptureData("y", 4, 1), } }); } } #if !NETFRAMEWORK // these tests currently fail on .NET Framework, and we need to check IsDynamicCodeCompiled but that doesn't exist on .NET Framework yield return(new object[] { engine, "@(a*)+?", "@", RegexOptions.None, new[] { new CaptureData("@", 0, 1) } }); if (!RegexHelpers.IsNonBacktracking(engine)) // atomic subexpressions aren't supported { yield return(new object[] { engine, @"()(?>\1+?).\b", "xxxx", RegexOptions.None, new[] { new CaptureData("x", 3, 1), } }); } if (engine != RegexEngine.Interpreter && // these tests currently fail with RegexInterpreter RuntimeFeature.IsDynamicCodeCompiled) // if dynamic code isn't compiled, RegexOptions.Compiled falls back to the interpreter, for which these tests currently fail { // Fails on interpreter and .NET Framework: [ActiveIssue("https://github.com/dotnet/runtime/issues/62094")] yield return(new object[] { engine, @"(?:){93}", "x", RegexOptions.None, new[] { new CaptureData("", 0, 0), new CaptureData("", 1, 0) } }); } #endif } }
public static IEnumerable <object[]> Matches_TestData() { foreach (RegexEngine engine in RegexHelpers.AvailableEngines) { yield return(new object[] { engine, "[0-9]", "12345asdfasdfasdfljkhsda67890", RegexOptions.None, new CaptureData[] { new CaptureData("1", 0, 1), new CaptureData("2", 1, 1), new CaptureData("3", 2, 1), new CaptureData("4", 3, 1), new CaptureData("5", 4, 1), new CaptureData("6", 24, 1), new CaptureData("7", 25, 1), new CaptureData("8", 26, 1), new CaptureData("9", 27, 1), new CaptureData("0", 28, 1), } }); yield return(new object[] { engine, "[a-z0-9]+", "[token1]? GARBAGEtoken2GARBAGE ;token3!", RegexOptions.None, new CaptureData[] { new CaptureData("token1", 1, 6), new CaptureData("token2", 17, 6), new CaptureData("token3", 32, 6) } }); yield return(new object[] { engine, "(abc){2}", " !abcabcasl dkfjasiduf 12343214-//asdfjzpiouxoifzuoxpicvql23r\\` #$3245,2345278 :asdfas & 100% @daeeffga (ryyy27343) poiweurwabcabcasdfalksdhfaiuyoiruqwer{234}/[(132387 + x)]'aaa''?", RegexOptions.None, new CaptureData[] { new CaptureData("abcabc", 2, 6), new CaptureData("abcabc", 125, 6) } }); yield return(new object[] { engine, @"\b\w*\b", "handling words of various lengths", RegexOptions.None, new CaptureData[] { new CaptureData("handling", 0, 8), new CaptureData("", 8, 0), new CaptureData("words", 9, 5), new CaptureData("", 14, 0), new CaptureData("of", 15, 2), new CaptureData("", 17, 0), new CaptureData("various", 18, 7), new CaptureData("", 25, 0), new CaptureData("lengths", 26, 7), new CaptureData("", 33, 0), } }); yield return(new object[] { engine, @"\b\w{2}\b", "handling words of various lengths", RegexOptions.None, new CaptureData[] { new CaptureData("of", 15, 2), } }); yield return(new object[] { engine, @"\w{6,}", "handling words of various lengths", RegexOptions.None, new CaptureData[] { new CaptureData("handling", 0, 8), new CaptureData("various", 18, 7), new CaptureData("lengths", 26, 7), } }); yield return(new object[] { engine, "[a-z]", "a", RegexOptions.None, new CaptureData[] { new CaptureData("a", 0, 1) } }); yield return(new object[] { engine, "[a-z]", "a1bc", RegexOptions.None, new CaptureData[] { new CaptureData("a", 0, 1), new CaptureData("b", 2, 1), new CaptureData("c", 3, 1) } }); yield return(new object[] { engine, "(?:ab|cd|ef|gh|i)j", "abj cdj efj ghjij", RegexOptions.None, new CaptureData[] { new CaptureData("abj", 0, 3), new CaptureData("cdj", 7, 3), new CaptureData("efj", 12, 3), new CaptureData("ghj", 26, 3), new CaptureData("ij", 29, 2), } }); // Using ^ with multiline yield return(new object[] { engine, "^", "", RegexOptions.Multiline, new[] { new CaptureData("", 0, 0) } }); yield return(new object[] { engine, "^", "\n\n\n", RegexOptions.Multiline, new[] { new CaptureData("", 0, 0), new CaptureData("", 1, 0), new CaptureData("", 2, 0), new CaptureData("", 3, 0) } }); yield return(new object[] { engine, "^abc", "abc\nabc \ndef abc \nab\nabc", RegexOptions.Multiline, new[] { new CaptureData("abc", 0, 3), new CaptureData("abc", 4, 3), new CaptureData("abc", 21, 3), } }); yield return(new object[] { engine, @"^\w{5}", "abc\ndefg\n\nhijkl\n", RegexOptions.Multiline, new[] { new CaptureData("hijkl", 10, 5), } }); yield return(new object[] { engine, @"^.*$", "abc\ndefg\n\nhijkl\n", RegexOptions.Multiline, new[] { new CaptureData("abc", 0, 3), new CaptureData("defg", 4, 4), new CaptureData("", 9, 0), new CaptureData("hijkl", 10, 5), new CaptureData("", 16, 0), } }); yield return(new object[] { engine, ".*", "abc", RegexOptions.None, new[] { new CaptureData("abc", 0, 3), new CaptureData("", 3, 0) } }); if (!PlatformDetection.IsNetFramework) { // .NET Framework missing fix in https://github.com/dotnet/runtime/pull/1075 yield return(new object[] { engine, @"[a -\-\b]", "a #.", RegexOptions.None, new CaptureData[] { new CaptureData("a", 0, 1), new CaptureData(" ", 1, 1), new CaptureData("#", 2, 1), } }); } if (!RegexHelpers.IsNonBacktracking(engine)) { yield return(new object[] { engine, @"foo\d+", "0123456789foo4567890foo1foo 0987", RegexOptions.RightToLeft, new CaptureData[] { new CaptureData("foo1", 20, 4), new CaptureData("foo4567890", 10, 10), } }); yield return(new object[] { engine, "(?(A)A123|C789)", "A123 B456 C789", RegexOptions.None, new CaptureData[] { new CaptureData("A123", 0, 4), new CaptureData("C789", 10, 4), } }); yield return(new object[] { engine, "(?(A)A123|C789)", "A123 B456 C789", RegexOptions.None, new CaptureData[] { new CaptureData("A123", 0, 4), new CaptureData("C789", 10, 4), } }); yield return(new object[] { engine, @"^.*$", "abc\ndefg\n\nhijkl\n", RegexOptions.Multiline | RegexOptions.RightToLeft, new[] { new CaptureData("", 16, 0), new CaptureData("hijkl", 10, 5), new CaptureData("", 9, 0), new CaptureData("defg", 4, 4), new CaptureData("abc", 0, 3), } }); if (!PlatformDetection.IsNetFramework) { // .NET Framework missing fix in https://github.com/dotnet/runtime/pull/993 yield return(new object[] { engine, "[^]", "every", RegexOptions.ECMAScript, new CaptureData[] { new CaptureData("e", 0, 1), new CaptureData("v", 1, 1), new CaptureData("e", 2, 1), new CaptureData("r", 3, 1), new CaptureData("y", 4, 1), } }); } } } }
public static IEnumerable <object[]> Split_TestData() { foreach (RegexEngine engine in RegexHelpers.AvailableEngines) { yield return(new object[] { engine, "", "", RegexOptions.None, 0, 0, new string[] { "", "" } }); yield return(new object[] { engine, "123", "abc", RegexOptions.None, 3, 0, new string[] { "abc" } }); yield return(new object[] { engine, " ", "word0 word1 word2 word3", RegexOptions.None, 32, 0, new string[] { "word0", "word1", "word2", "word3" } }); yield return(new object[] { engine, ":", "kkk:lll:mmm:nnn:ooo", RegexOptions.None, 19, 0, new string[] { "kkk", "lll", "mmm", "nnn", "ooo" } }); yield return(new object[] { engine, ":", "kkk:lll:mmm:nnn:ooo", RegexOptions.None, 0, 0, new string[] { "kkk", "lll", "mmm", "nnn", "ooo" } }); // IgnoreCase yield return(new object[] { engine, "[abc]", "1A2B3C4", RegexOptions.IgnoreCase, 7, 0, new string[] { "1", "2", "3", "4" } }); // Custom index yield return(new object[] { engine, ":", "kkk:lll:mmm:nnn:ooo", RegexOptions.None, 2, 0, new string[] { "kkk", "lll:mmm:nnn:ooo" } }); yield return(new object[] { engine, ":", "kkk:lll:mmm:nnn:ooo", RegexOptions.None, 3, 6, new string[] { "kkk:lll", "mmm", "nnn:ooo" } }); // Tricky corner cases involving empty matches of anchors yield return(new object[] { engine, @"\b", "Hello World!", RegexOptions.None, 3, 6, new string[] { "Hello ", "World", "!" } }); yield return(new object[] { engine, @"\b", "Hello World!", RegexOptions.None, 0, 0, new string[] { "", "Hello", " ", "World", "!" } }); yield return(new object[] { engine, @"^", "Hello \nWorld!", RegexOptions.None | RegexOptions.Multiline, 0, 0, new string[] { "", "Hello \n", "World!" } }); yield return(new object[] { engine, @"$", "Hello \nWorld!", RegexOptions.None | RegexOptions.Multiline, 0, 0, new string[] { "Hello ", "\nWorld!", "" } }); if (!RegexHelpers.IsNonBacktracking(engine)) { yield return(new object[] { engine, @"(\s)?(-)", "once -upon-a time", RegexOptions.None, 17, 0, new string[] { "once", " ", "-", "upon", "-", "a time" } }); yield return(new object[] { engine, @"(\s)?(-)", "once upon a time", RegexOptions.None, 16, 0, new string[] { "once upon a time" } }); yield return(new object[] { engine, @"(\s)?(-)", "once - -upon- a- time", RegexOptions.None, 21, 0, new string[] { "once", " ", "-", "", " ", "-", "upon", "-", " a", "-", " time" } }); yield return(new object[] { engine, "a(.)c(.)e", "123abcde456aBCDe789", RegexOptions.None, 19, 0, new string[] { "123", "b", "d", "456aBCDe789" } }); yield return(new object[] { engine, "a(.)c(.)e", "123abcde456aBCDe789", RegexOptions.IgnoreCase, 19, 0, new string[] { "123", "b", "d", "456", "B", "D", "789" } }); yield return(new object[] { engine, "a(?<dot1>.)c(.)e", "123abcde456aBCDe789", RegexOptions.None, 19, 0, new string[] { "123", "d", "b", "456aBCDe789" } }); yield return(new object[] { engine, "a(?<dot1>.)c(.)e", "123abcde456aBCDe789", RegexOptions.IgnoreCase, 19, 0, new string[] { "123", "d", "b", "456", "D", "B", "789" } }); // RightToLeft yield return(new object[] { engine, "", "", RegexOptions.RightToLeft, 0, 0, new string[] { "", "" } }); yield return(new object[] { engine, "123", "abc", RegexOptions.RightToLeft, 3, 0, new string[] { "abc" } }); yield return(new object[] { engine, "a(.)c(.)e", "123abcde456aBCDe789", RegexOptions.RightToLeft, 19, 19, new string[] { "123", "d", "b", "456aBCDe789" } }); yield return(new object[] { engine, "a(.)c(.)e", "123abcde456aBCDe789", RegexOptions.RightToLeft | RegexOptions.IgnoreCase, 19, 19, new string[] { "123", "d", "b", "456", "D", "B", "789" } }); yield return(new object[] { engine, "a(?<dot1>.)c(.)e", "123abcde456aBCDe789", RegexOptions.RightToLeft, 19, 19, new string[] { "123", "b", "d", "456aBCDe789" } }); yield return(new object[] { engine, "a(?<dot1>.)c(.)e", "123abcde456aBCDe789", RegexOptions.RightToLeft | RegexOptions.IgnoreCase, 19, 19, new string[] { "123", "b", "d", "456", "B", "D", "789" } }); yield return(new object[] { engine, "foo", "0123456789foo4567890foo ", RegexOptions.RightToLeft, 32, 32, new string[] { "0123456789", "4567890", " " } }); yield return(new object[] { engine, @"\d", "1a2b3c4d5e6f7g8h9i0k", RegexOptions.RightToLeft, 20, 20, new string[] { "", "a", "b", "c", "d", "e", "f", "g", "h", "i", "k" } }); yield return(new object[] { engine, @"\d", "1a2b3c4d5e6f7g8h9i0k", RegexOptions.RightToLeft, 10, 20, new string[] { "1a", "b", "c", "d", "e", "f", "g", "h", "i", "k" } }); yield return(new object[] { engine, @"\d", "1a2b3c4d5e6f7g8h9i0k", RegexOptions.RightToLeft, 2, 20, new string[] { "1a2b3c4d5e6f7g8h9i", "k" } }); yield return(new object[] { engine, @"\d", "1a2b3c4d5e6f7g8h9i0k", RegexOptions.RightToLeft, 1, 20, new string[] { "1a2b3c4d5e6f7g8h9i0k" } }); // Anchors yield return(new object[] { engine, @"(?<=\G..)(?=..)", "aabbccdd", RegexOptions.None, 8, 0, new string[] { "aa", "bb", "cc", "dd" } }); } if (RegexHelpers.IsNonBacktracking(engine)) { // RegexOptions.NonBacktracking also ignores named captures as if they were not given yield return(new object[] { engine, "a(?<dot1>.)c(.)e", "123abcde456aBCDe789", RegexOptions.None, 19, 0, new string[] { "123", "456aBCDe789" } }); yield return(new object[] { engine, "a(?<dot1>.)c(.)e", "123abcde456aBCDe789", RegexOptions.IgnoreCase, 19, 0, new string[] { "123", "456", "789" } }); } // RegexOptions.NonBacktracking is similar to RegexOptions.ExplicitCapture when there are no explicit capture names because NonBacktracking does not support captures // This is the reason for including the RegexOptions.ExplicitCapture options also to check that the results are the same in this case foreach (RegexOptions options in new[] { RegexOptions.None, RegexOptions.ExplicitCapture }) { if (options != RegexOptions.None || RegexHelpers.IsNonBacktracking(engine)) { yield return(new object[] { engine, @"(\s)?(-)", "once -upon-a time", options, 17, 0, new string[] { "once", "upon", "a time" } }); yield return(new object[] { engine, @"(\s)?(-)", "once upon a time", options, 16, 0, new string[] { "once upon a time" } }); yield return(new object[] { engine, @"(\s)?(-)", "once - -upon- a- time", options, 21, 0, new string[] { "once", "", "upon", " a", " time" } }); yield return(new object[] { engine, "a(.)c(.)e", "123abcde456aBCDe789", options, 19, 0, new string[] { "123", "456aBCDe789" } }); yield return(new object[] { engine, "a.c.e", "123abcde456aBCDe789", options, 19, 0, new string[] { "123", "456aBCDe789" } }); yield return(new object[] { engine, "a.c.e", "123abcde456aBCDe789", options | RegexOptions.IgnoreCase, 19, 0, new string[] { "123", "456", "789" } }); } } } }