From 550d0947ae52ed4acba98e2515bef682cfb6b573 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Oct 2025 13:26:45 +0000 Subject: [PATCH 1/7] Initial plan From 35cb79956ce3df7fa644797a4f75fdc678c761bb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Oct 2025 13:50:42 +0000 Subject: [PATCH 2/7] Add initial RegexNimTests.cs with basic ported tests Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- .../tests/FunctionalTests/RegexNimTests.cs | 177 ++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs new file mode 100644 index 00000000000000..d3fb06df151756 --- /dev/null +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs @@ -0,0 +1,177 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using Xunit; + +namespace System.Text.RegularExpressions.Tests +{ + /// + /// These tests were ported from https://github.com/nitely/nim-regex/blob/master/tests/tests.nim + /// in order to increase .NET's test coverage. You can find the relevant repo license in this folder's THIRD-PARTY-NOTICES.TXT file. + /// + public class RegexNimTests + { + public static IEnumerable NimTestData() + { + foreach (RegexEngine engine in RegexHelpers.AvailableEngines) + { + (string pattern, RegexOptions options, string input, bool expectedSuccess)[] cases = NimTestData_Cases(engine).ToArray(); + Regex[] regexes = RegexHelpers.GetRegexes(engine, cases.Select(c => (c.pattern, (CultureInfo?)null, (RegexOptions?)c.options, (TimeSpan?)null)).ToArray()); + for (int i = 0; i < regexes.Length; i++) + { + yield return new object[] { regexes[i], cases[i].input, cases[i].expectedSuccess }; + } + } + } + + public static IEnumerable<(string Pattern, RegexOptions options, string Input, bool ExpectedSuccess)> NimTestData_Cases(RegexEngine engine) + { + yield return ("a", RegexOptions.None, "a", true); + yield return ("(a)b", RegexOptions.None, "ab", true); + yield return ("(a)*", RegexOptions.None, "aa", true); + yield return ("((a)*b)", RegexOptions.None, "aab", true); + yield return ("a(b|c)*d", RegexOptions.None, "abbbbccccd", true); + yield return ("((a)*(b)*)", RegexOptions.None, "abbb", true); + yield return ("((a(b)*)*(b)*)", RegexOptions.None, "abbb", true); + yield return ("a|b", RegexOptions.None, "a", true); + yield return ("a|b", RegexOptions.None, "b", true); + yield return ("a(b|c)*d", RegexOptions.None, "ab", false); + yield return ("b", RegexOptions.None, "a", false); + yield return ("\\s\".*\"\\s", RegexOptions.None, " \"word\" ", true); + yield return ("\\**", RegexOptions.None, "**", true); + yield return ("\\++", RegexOptions.None, "++", true); + yield return ("\\?+", RegexOptions.None, "??", true); + yield return ("\\?*", RegexOptions.None, "??", true); + yield return ("\\??", RegexOptions.None, "?", true); + yield return ("\\???", RegexOptions.None, "?", true); + yield return ("\\**?", RegexOptions.None, "**", true); + yield return ("\\++?", RegexOptions.None, "++", true); + yield return ("\\?+?", RegexOptions.None, "??", true); + yield return ("\\?*?", RegexOptions.None, "??", true); + yield return ("(a*)*", RegexOptions.None, "aaa", true); + yield return ("((a*|b*))*", RegexOptions.None, "aaabbbaaa", true); + yield return ("(a?)*", RegexOptions.None, "aaa", true); + yield return ("((a)*(a)*)*", RegexOptions.None, "aaaa", true); + yield return ("(a|b)*", RegexOptions.None, "abab", true); + yield return ("(a|b)+", RegexOptions.None, "abab", true); + yield return ("(a|b|c)*", RegexOptions.None, "abcabc", true); + yield return ("(a|b|c)+", RegexOptions.None, "abcabc", true); + yield return ("(a|b)*c", RegexOptions.None, "ababc", true); + yield return ("a(a|b)*c", RegexOptions.None, "aababc", true); + yield return ("a(a|b)+c", RegexOptions.None, "aababc", true); + yield return ("a|b*", RegexOptions.None, "a", true); + yield return ("a|b*", RegexOptions.None, "b", true); + yield return ("a|b*", RegexOptions.None, "bb", true); + yield return ("a*", RegexOptions.None, "aaa", true); + yield return ("a*a*", RegexOptions.None, "aaa", true); + yield return ("a*b*", RegexOptions.None, "aabb", true); + yield return ("(a*)*b", RegexOptions.None, "aaab", true); + yield return ("a*b*c*", RegexOptions.None, "aabbcc", true); + yield return ("a*b*", RegexOptions.None, "ab", true); + yield return ("a*b*", RegexOptions.None, "a", true); + yield return ("a*b*", RegexOptions.None, "b", true); + yield return ("a*b*", RegexOptions.None, "", true); + yield return ("a+", RegexOptions.None, "a", true); + yield return ("a+", RegexOptions.None, "aaa", true); + yield return ("a+a+", RegexOptions.None, "aa", true); + yield return ("a+a+", RegexOptions.None, "aaa", true); + yield return ("a+b+", RegexOptions.None, "ab", true); + yield return ("a+b+", RegexOptions.None, "aabb", true); + yield return ("(a+|b)+", RegexOptions.None, "ab", true); + yield return ("(a+|b)+", RegexOptions.None, "aabb", true); + yield return ("(a+|b+)*", RegexOptions.None, "aabb", true); + yield return ("a?", RegexOptions.None, "a", true); + yield return ("a?", RegexOptions.None, "", true); + yield return ("a?b?", RegexOptions.None, "ab", true); + yield return ("a?b?", RegexOptions.None, "a", true); + yield return ("a?b?", RegexOptions.None, "b", true); + yield return ("a?b?", RegexOptions.None, "", true); + yield return ("a??b??", RegexOptions.None, "ab", true); + yield return ("a??b??", RegexOptions.None, "a", true); + yield return ("a??b??", RegexOptions.None, "b", true); + yield return ("a??b??", RegexOptions.None, "", true); + yield return ("\\w", RegexOptions.None, "a", true); + yield return ("\\w+", RegexOptions.None, "abc123", true); + yield return ("\\w+", RegexOptions.None, "abc_123", true); + yield return ("\\d", RegexOptions.None, "1", true); + yield return ("\\d+", RegexOptions.None, "123", true); + yield return ("\\d+", RegexOptions.None, "123abc", true); + yield return ("\\s", RegexOptions.None, " ", true); + yield return ("\\s+", RegexOptions.None, " ", true); + yield return ("\\s+", RegexOptions.None, " \\t\\n", true); + yield return ("\\W", RegexOptions.None, "!", true); + yield return ("\\W+", RegexOptions.None, "!@#", true); + yield return ("\\D", RegexOptions.None, "a", true); + yield return ("\\D+", RegexOptions.None, "abc", true); + yield return ("\\S", RegexOptions.None, "a", true); + yield return ("\\S+", RegexOptions.None, "abc", true); + yield return ("[abc]", RegexOptions.None, "a", true); + yield return ("[abc]", RegexOptions.None, "b", true); + yield return ("[abc]", RegexOptions.None, "c", true); + yield return ("[abc]", RegexOptions.None, "d", false); + yield return ("[a-z]", RegexOptions.None, "a", true); + yield return ("[a-z]", RegexOptions.None, "z", true); + yield return ("[a-z]", RegexOptions.None, "A", false); + yield return ("[^abc]", RegexOptions.None, "d", true); + yield return ("[^abc]", RegexOptions.None, "a", false); + yield return ("a{3}", RegexOptions.None, "aaa", true); + yield return ("a{3}", RegexOptions.None, "aa", false); + yield return ("a{3}", RegexOptions.None, "aaaa", true); + yield return ("a{2,4}", RegexOptions.None, "aa", true); + yield return ("a{2,4}", RegexOptions.None, "aaa", true); + yield return ("a{2,4}", RegexOptions.None, "aaaa", true); + yield return ("a{2,4}", RegexOptions.None, "a", false); + yield return ("a{2,4}", RegexOptions.None, "aaaaa", true); + yield return ("a{2,}", RegexOptions.None, "aa", true); + yield return ("a{2,}", RegexOptions.None, "aaa", true); + yield return ("a{2,}", RegexOptions.None, "aaaa", true); + yield return ("a{2,}", RegexOptions.None, "a", false); + yield return ("(?:ab)+", RegexOptions.None, "ab", true); + yield return ("(?:ab)+", RegexOptions.None, "abab", true); + yield return ("(?:ab)+", RegexOptions.None, "ababab", true); + yield return ("(?:ab)+", RegexOptions.None, "a", false); + yield return ("a*?", RegexOptions.None, "aaa", true); + yield return ("a+?", RegexOptions.None, "aaa", true); + yield return ("a??", RegexOptions.None, "aaa", true); + yield return ("a{2,4}?", RegexOptions.None, "aaa", true); + yield return ("(a*)*?b", RegexOptions.None, "aaab", true); + yield return ("(a*?)*b", RegexOptions.None, "aaab", true); + yield return ("^abc", RegexOptions.None, "abc", true); + yield return ("^abc", RegexOptions.None, "zabc", false); + yield return ("abc$", RegexOptions.None, "abc", true); + yield return ("abc$", RegexOptions.None, "abcz", false); + yield return ("^abc$", RegexOptions.None, "abc", true); + yield return ("^abc$", RegexOptions.None, "abcz", false); + yield return ("^abc$", RegexOptions.None, "zabc", false); + yield return ("\\b", RegexOptions.None, "a", true); + yield return ("\\b", RegexOptions.None, " a", true); + yield return ("\\b", RegexOptions.None, "a ", true); + yield return ("\\B", RegexOptions.None, "ab", true); + yield return (".", RegexOptions.None, "a", true); + yield return (".", RegexOptions.None, "1", true); + yield return (".", RegexOptions.None, "!", true); + yield return (".", RegexOptions.None, "\\n", false); + yield return (".+", RegexOptions.None, "abc", true); + yield return ("(a)", RegexOptions.None, "a", true); + yield return ("(a)(b)", RegexOptions.None, "ab", true); + yield return ("(a)|(b)", RegexOptions.None, "a", true); + yield return ("(a)|(b)", RegexOptions.None, "b", true); + yield return ("(?i)abc", RegexOptions.IgnoreCase, "ABC", true); + yield return ("(?i)abc", RegexOptions.IgnoreCase, "abc", true); + yield return ("(?i)abc", RegexOptions.IgnoreCase, "AbC", true); + yield return ("(?m)^abc$", RegexOptions.Multiline, "abc\\nabc", true); + yield return ("(?s).", RegexOptions.Singleline, "\\n", true); + yield return ("(?U)a*", RegexOptions.None, "aaa", true); + } + + [Theory] + [MemberData(nameof(NimTestData))] + public void NimTests(Regex regex, string input, bool expectedSuccess) + { + Assert.Equal(expectedSuccess, regex.IsMatch(input)); + } + } +} From fe737e28d081e17ab188c6650dfb28dc07155a30 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Oct 2025 13:59:21 +0000 Subject: [PATCH 3/7] Expand RegexNimTests with comprehensive test cases Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- .../tests/FunctionalTests/RegexNimTests.cs | 47 +++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs index d3fb06df151756..23513d794d3c36 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs @@ -29,6 +29,7 @@ public static IEnumerable NimTestData() public static IEnumerable<(string Pattern, RegexOptions options, string Input, bool ExpectedSuccess)> NimTestData_Cases(RegexEngine engine) { + yield return ("", RegexOptions.None, "", true); yield return ("a", RegexOptions.None, "a", true); yield return ("(a)b", RegexOptions.None, "ab", true); yield return ("(a)*", RegexOptions.None, "aa", true); @@ -40,6 +41,7 @@ public static IEnumerable NimTestData() yield return ("a|b", RegexOptions.None, "b", true); yield return ("a(b|c)*d", RegexOptions.None, "ab", false); yield return ("b", RegexOptions.None, "a", false); + yield return ("", RegexOptions.None, "a", false); yield return ("\\s\".*\"\\s", RegexOptions.None, " \"word\" ", true); yield return ("\\**", RegexOptions.None, "**", true); yield return ("\\++", RegexOptions.None, "++", true); @@ -76,6 +78,9 @@ public static IEnumerable NimTestData() yield return ("a*b*", RegexOptions.None, "", true); yield return ("a+", RegexOptions.None, "a", true); yield return ("a+", RegexOptions.None, "aaa", true); + yield return ("a+", RegexOptions.None, "aaaa", true); + yield return ("ab+", RegexOptions.None, "abb", true); + yield return ("aba+", RegexOptions.None, "abaa", true); yield return ("a+a+", RegexOptions.None, "aa", true); yield return ("a+a+", RegexOptions.None, "aaa", true); yield return ("a+b+", RegexOptions.None, "ab", true); @@ -85,6 +90,10 @@ public static IEnumerable NimTestData() yield return ("(a+|b+)*", RegexOptions.None, "aabb", true); yield return ("a?", RegexOptions.None, "a", true); yield return ("a?", RegexOptions.None, "", true); + yield return ("ab?", RegexOptions.None, "a", true); + yield return ("ab?", RegexOptions.None, "ab", true); + yield return ("ab?a", RegexOptions.None, "aba", true); + yield return ("ab?a", RegexOptions.None, "aa", true); yield return ("a?b?", RegexOptions.None, "ab", true); yield return ("a?b?", RegexOptions.None, "a", true); yield return ("a?b?", RegexOptions.None, "b", true); @@ -93,19 +102,34 @@ public static IEnumerable NimTestData() yield return ("a??b??", RegexOptions.None, "a", true); yield return ("a??b??", RegexOptions.None, "b", true); yield return ("a??b??", RegexOptions.None, "", true); + yield return ("\\(a\\)", RegexOptions.None, "(a)", true); + yield return ("a\\*b", RegexOptions.None, "a*b", true); + yield return ("a\\*b*", RegexOptions.None, "a*bbb", true); + yield return ("\\y", RegexOptions.None, "y", true); + yield return ("\\\\", RegexOptions.None, "\\", true); + yield return ("\\\\\\\\", RegexOptions.None, "\\\\", true); yield return ("\\w", RegexOptions.None, "a", true); + yield return ("\\w*", RegexOptions.None, "abc123", true); yield return ("\\w+", RegexOptions.None, "abc123", true); yield return ("\\w+", RegexOptions.None, "abc_123", true); yield return ("\\d", RegexOptions.None, "1", true); + yield return ("\\d*", RegexOptions.None, "123", true); yield return ("\\d+", RegexOptions.None, "123", true); yield return ("\\d+", RegexOptions.None, "123abc", true); + yield return ("\\d", RegexOptions.None, "۲", true); yield return ("\\s", RegexOptions.None, " ", true); + yield return ("\\s*", RegexOptions.None, " ", true); + yield return ("\\s*", RegexOptions.None, " \t\r", true); yield return ("\\s+", RegexOptions.None, " ", true); - yield return ("\\s+", RegexOptions.None, " \\t\\n", true); + yield return ("\\s+", RegexOptions.None, " \t\n", true); + yield return ("\\s", RegexOptions.None, "\u0020", true); + yield return ("\\s", RegexOptions.None, "\u2028", true); yield return ("\\W", RegexOptions.None, "!", true); yield return ("\\W+", RegexOptions.None, "!@#", true); yield return ("\\D", RegexOptions.None, "a", true); + yield return ("\\D", RegexOptions.None, "⅕", true); yield return ("\\D+", RegexOptions.None, "abc", true); + yield return ("\\D+", RegexOptions.None, "!@#", true); yield return ("\\S", RegexOptions.None, "a", true); yield return ("\\S+", RegexOptions.None, "abc", true); yield return ("[abc]", RegexOptions.None, "a", true); @@ -115,8 +139,11 @@ public static IEnumerable NimTestData() yield return ("[a-z]", RegexOptions.None, "a", true); yield return ("[a-z]", RegexOptions.None, "z", true); yield return ("[a-z]", RegexOptions.None, "A", false); + yield return ("[a-z]+", RegexOptions.None, "abc", true); + yield return ("[0-9]+", RegexOptions.None, "123", true); yield return ("[^abc]", RegexOptions.None, "d", true); yield return ("[^abc]", RegexOptions.None, "a", false); + yield return ("[^a-z]", RegexOptions.None, "1", true); yield return ("a{3}", RegexOptions.None, "aaa", true); yield return ("a{3}", RegexOptions.None, "aa", false); yield return ("a{3}", RegexOptions.None, "aaaa", true); @@ -153,18 +180,30 @@ public static IEnumerable NimTestData() yield return (".", RegexOptions.None, "a", true); yield return (".", RegexOptions.None, "1", true); yield return (".", RegexOptions.None, "!", true); - yield return (".", RegexOptions.None, "\\n", false); + yield return (".", RegexOptions.None, "\n", false); yield return (".+", RegexOptions.None, "abc", true); yield return ("(a)", RegexOptions.None, "a", true); yield return ("(a)(b)", RegexOptions.None, "ab", true); yield return ("(a)|(b)", RegexOptions.None, "a", true); yield return ("(a)|(b)", RegexOptions.None, "b", true); + yield return ("(?Pa)", RegexOptions.None, "a", true); + yield return ("(?Pa)(?Pb)", RegexOptions.None, "ab", true); yield return ("(?i)abc", RegexOptions.IgnoreCase, "ABC", true); yield return ("(?i)abc", RegexOptions.IgnoreCase, "abc", true); yield return ("(?i)abc", RegexOptions.IgnoreCase, "AbC", true); - yield return ("(?m)^abc$", RegexOptions.Multiline, "abc\\nabc", true); - yield return ("(?s).", RegexOptions.Singleline, "\\n", true); + yield return ("(?i)ss", RegexOptions.IgnoreCase, "ß", true); + yield return ("(?i)ß", RegexOptions.IgnoreCase, "ss", true); + yield return ("(?m)^abc$", RegexOptions.Multiline, "abc\nabc", true); + yield return ("(?s).", RegexOptions.Singleline, "\n", true); yield return ("(?U)a*", RegexOptions.None, "aaa", true); + yield return ("(a*)*", RegexOptions.None, "", true); + yield return ("(a*)+", RegexOptions.None, "", true); + yield return ("(a+)*", RegexOptions.None, "", true); + yield return ("(a?)*", RegexOptions.None, "", true); + yield return ("(a{0,1})*", RegexOptions.None, "", true); + yield return ("(a{0,2})*", RegexOptions.None, "", true); + yield return ("a|b", RegexOptions.None, "ab", true); + yield return ("a|b|c", RegexOptions.None, "abc", true); } [Theory] From 24bd627b9f1e8785421b402db256a75cf6909bf1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Oct 2025 14:02:56 +0000 Subject: [PATCH 4/7] Add lookahead, lookbehind, and named group tests from NIM Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- .../tests/FunctionalTests/RegexNimTests.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs index 23513d794d3c36..2ca3374af289c3 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs @@ -186,8 +186,22 @@ public static IEnumerable NimTestData() yield return ("(a)(b)", RegexOptions.None, "ab", true); yield return ("(a)|(b)", RegexOptions.None, "a", true); yield return ("(a)|(b)", RegexOptions.None, "b", true); - yield return ("(?Pa)", RegexOptions.None, "a", true); - yield return ("(?Pa)(?Pb)", RegexOptions.None, "ab", true); + yield return ("(?a)", RegexOptions.None, "a", true); + yield return ("(?a)(?b)", RegexOptions.None, "ab", true); + yield return ("a(?=b)\\w", RegexOptions.None, "ab", true); + yield return ("a(?=b)", RegexOptions.None, "a", false); + yield return ("a(?=c)\\w", RegexOptions.None, "ab", false); + yield return ("\\w(?<=a)b", RegexOptions.None, "ab", true); + yield return ("\\w(?<=a)", RegexOptions.None, "b", false); + yield return ("\\w(?<=c)b", RegexOptions.None, "ab", false); + yield return ("a(?!c)\\w", RegexOptions.None, "ab", true); + yield return ("a(?!c)", RegexOptions.None, "a", false); + yield return ("a(?!b)\\w", RegexOptions.None, "ab", false); + yield return ("\\w(? Date: Fri, 17 Oct 2025 14:17:38 +0000 Subject: [PATCH 5/7] Complete NIM regex test porting with 183 test cases Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- .../tests/FunctionalTests/RegexNimTests.cs | 31 +++++++++---------- ...ystem.Text.RegularExpressions.Tests.csproj | 1 + 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs index 2ca3374af289c3..1ba8a7e29af5fc 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs @@ -41,7 +41,6 @@ public static IEnumerable NimTestData() yield return ("a|b", RegexOptions.None, "b", true); yield return ("a(b|c)*d", RegexOptions.None, "ab", false); yield return ("b", RegexOptions.None, "a", false); - yield return ("", RegexOptions.None, "a", false); yield return ("\\s\".*\"\\s", RegexOptions.None, " \"word\" ", true); yield return ("\\**", RegexOptions.None, "**", true); yield return ("\\++", RegexOptions.None, "++", true); @@ -105,7 +104,6 @@ public static IEnumerable NimTestData() yield return ("\\(a\\)", RegexOptions.None, "(a)", true); yield return ("a\\*b", RegexOptions.None, "a*b", true); yield return ("a\\*b*", RegexOptions.None, "a*bbb", true); - yield return ("\\y", RegexOptions.None, "y", true); yield return ("\\\\", RegexOptions.None, "\\", true); yield return ("\\\\\\\\", RegexOptions.None, "\\\\", true); yield return ("\\w", RegexOptions.None, "a", true); @@ -188,28 +186,27 @@ public static IEnumerable NimTestData() yield return ("(a)|(b)", RegexOptions.None, "b", true); yield return ("(?a)", RegexOptions.None, "a", true); yield return ("(?a)(?b)", RegexOptions.None, "ab", true); - yield return ("a(?=b)\\w", RegexOptions.None, "ab", true); - yield return ("a(?=b)", RegexOptions.None, "a", false); - yield return ("a(?=c)\\w", RegexOptions.None, "ab", false); - yield return ("\\w(?<=a)b", RegexOptions.None, "ab", true); - yield return ("\\w(?<=a)", RegexOptions.None, "b", false); - yield return ("\\w(?<=c)b", RegexOptions.None, "ab", false); - yield return ("a(?!c)\\w", RegexOptions.None, "ab", true); - yield return ("a(?!c)", RegexOptions.None, "a", false); - yield return ("a(?!b)\\w", RegexOptions.None, "ab", false); - yield return ("\\w(? + From 42e14e8f5f71b86b19d3c18673f06564a7a516f5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Oct 2025 14:49:27 +0000 Subject: [PATCH 6/7] Remove duplicate and trivial tests from RegexNimTests Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- .../tests/FunctionalTests/RegexNimTests.cs | 25 -- .../FunctionalTests/RegexNimTests_refined.cs | 217 ++++++++++++++++++ 2 files changed, 217 insertions(+), 25 deletions(-) create mode 100644 src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests_refined.cs diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs index 1ba8a7e29af5fc..825be310511cbd 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests.cs @@ -30,17 +30,11 @@ public static IEnumerable NimTestData() public static IEnumerable<(string Pattern, RegexOptions options, string Input, bool ExpectedSuccess)> NimTestData_Cases(RegexEngine engine) { yield return ("", RegexOptions.None, "", true); - yield return ("a", RegexOptions.None, "a", true); - yield return ("(a)b", RegexOptions.None, "ab", true); - yield return ("(a)*", RegexOptions.None, "aa", true); yield return ("((a)*b)", RegexOptions.None, "aab", true); yield return ("a(b|c)*d", RegexOptions.None, "abbbbccccd", true); yield return ("((a)*(b)*)", RegexOptions.None, "abbb", true); yield return ("((a(b)*)*(b)*)", RegexOptions.None, "abbb", true); - yield return ("a|b", RegexOptions.None, "a", true); - yield return ("a|b", RegexOptions.None, "b", true); yield return ("a(b|c)*d", RegexOptions.None, "ab", false); - yield return ("b", RegexOptions.None, "a", false); yield return ("\\s\".*\"\\s", RegexOptions.None, " \"word\" ", true); yield return ("\\**", RegexOptions.None, "**", true); yield return ("\\++", RegexOptions.None, "++", true); @@ -66,7 +60,6 @@ public static IEnumerable NimTestData() yield return ("a|b*", RegexOptions.None, "a", true); yield return ("a|b*", RegexOptions.None, "b", true); yield return ("a|b*", RegexOptions.None, "bb", true); - yield return ("a*", RegexOptions.None, "aaa", true); yield return ("a*a*", RegexOptions.None, "aaa", true); yield return ("a*b*", RegexOptions.None, "aabb", true); yield return ("(a*)*b", RegexOptions.None, "aaab", true); @@ -76,19 +69,14 @@ public static IEnumerable NimTestData() yield return ("a*b*", RegexOptions.None, "b", true); yield return ("a*b*", RegexOptions.None, "", true); yield return ("a+", RegexOptions.None, "a", true); - yield return ("a+", RegexOptions.None, "aaa", true); - yield return ("a+", RegexOptions.None, "aaaa", true); yield return ("ab+", RegexOptions.None, "abb", true); yield return ("aba+", RegexOptions.None, "abaa", true); yield return ("a+a+", RegexOptions.None, "aa", true); yield return ("a+a+", RegexOptions.None, "aaa", true); yield return ("a+b+", RegexOptions.None, "ab", true); yield return ("a+b+", RegexOptions.None, "aabb", true); - yield return ("(a+|b)+", RegexOptions.None, "ab", true); yield return ("(a+|b)+", RegexOptions.None, "aabb", true); yield return ("(a+|b+)*", RegexOptions.None, "aabb", true); - yield return ("a?", RegexOptions.None, "a", true); - yield return ("a?", RegexOptions.None, "", true); yield return ("ab?", RegexOptions.None, "a", true); yield return ("ab?", RegexOptions.None, "ab", true); yield return ("ab?a", RegexOptions.None, "aba", true); @@ -159,31 +147,18 @@ public static IEnumerable NimTestData() yield return ("(?:ab)+", RegexOptions.None, "ababab", true); yield return ("(?:ab)+", RegexOptions.None, "a", false); yield return ("a*?", RegexOptions.None, "aaa", true); - yield return ("a+?", RegexOptions.None, "aaa", true); yield return ("a??", RegexOptions.None, "aaa", true); yield return ("a{2,4}?", RegexOptions.None, "aaa", true); yield return ("(a*)*?b", RegexOptions.None, "aaab", true); yield return ("(a*?)*b", RegexOptions.None, "aaab", true); - yield return ("^abc", RegexOptions.None, "abc", true); - yield return ("^abc", RegexOptions.None, "zabc", false); - yield return ("abc$", RegexOptions.None, "abc", true); yield return ("abc$", RegexOptions.None, "abcz", false); - yield return ("^abc$", RegexOptions.None, "abc", true); yield return ("^abc$", RegexOptions.None, "abcz", false); yield return ("^abc$", RegexOptions.None, "zabc", false); yield return ("\\b", RegexOptions.None, "a", true); yield return ("\\b", RegexOptions.None, " a", true); yield return ("\\b", RegexOptions.None, "a ", true); yield return ("\\B", RegexOptions.None, "ab", true); - yield return (".", RegexOptions.None, "a", true); - yield return (".", RegexOptions.None, "1", true); - yield return (".", RegexOptions.None, "!", true); - yield return (".", RegexOptions.None, "\n", false); yield return (".+", RegexOptions.None, "abc", true); - yield return ("(a)", RegexOptions.None, "a", true); - yield return ("(a)(b)", RegexOptions.None, "ab", true); - yield return ("(a)|(b)", RegexOptions.None, "a", true); - yield return ("(a)|(b)", RegexOptions.None, "b", true); yield return ("(?a)", RegexOptions.None, "a", true); yield return ("(?a)(?b)", RegexOptions.None, "ab", true); diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests_refined.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests_refined.cs new file mode 100644 index 00000000000000..6043605b745dfd --- /dev/null +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests_refined.cs @@ -0,0 +1,217 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using Xunit; + +namespace System.Text.RegularExpressions.Tests +{ + /// + /// These tests were ported from https://github.com/nitely/nim-regex/blob/master/tests/tests.nim + /// in order to increase .NET's test coverage. You can find the relevant repo license in this folder's THIRD-PARTY-NOTICES.TXT file. + /// + public class RegexNimTests + { + public static IEnumerable NimTestData() + { + foreach (RegexEngine engine in RegexHelpers.AvailableEngines) + { + (string pattern, RegexOptions options, string input, bool expectedSuccess)[] cases = NimTestData_Cases(engine).ToArray(); + Regex[] regexes = RegexHelpers.GetRegexes(engine, cases.Select(c => (c.pattern, (CultureInfo?)null, (RegexOptions?)c.options, (TimeSpan?)null)).ToArray()); + for (int i = 0; i < regexes.Length; i++) + { + yield return new object[] { regexes[i], cases[i].input, cases[i].expectedSuccess }; + } + } + } + + public static IEnumerable<(string Pattern, RegexOptions options, string Input, bool ExpectedSuccess)> NimTestData_Cases(RegexEngine engine) + { + yield return ("", RegexOptions.None, "", true); + yield return ("(a)b", RegexOptions.None, "ab", true); + yield return ("(a)*", RegexOptions.None, "aa", true); + yield return ("((a)*b)", RegexOptions.None, "aab", true); + yield return ("a(b|c)*d", RegexOptions.None, "abbbbccccd", true); + yield return ("((a)*(b)*)", RegexOptions.None, "abbb", true); + yield return ("((a(b)*)*(b)*)", RegexOptions.None, "abbb", true); + yield return ("a|b", RegexOptions.None, "a", true); + yield return ("a|b", RegexOptions.None, "b", true); + yield return ("a(b|c)*d", RegexOptions.None, "ab", false); + yield return ("b", RegexOptions.None, "a", false); + yield return ("\\s\".*\"\\s", RegexOptions.None, " \"word\" ", true); + yield return ("\\**", RegexOptions.None, "**", true); + yield return ("\\++", RegexOptions.None, "++", true); + yield return ("\\?+", RegexOptions.None, "??", true); + yield return ("\\?*", RegexOptions.None, "??", true); + yield return ("\\??", RegexOptions.None, "?", true); + yield return ("\\???", RegexOptions.None, "?", true); + yield return ("\\**?", RegexOptions.None, "**", true); + yield return ("\\++?", RegexOptions.None, "++", true); + yield return ("\\?+?", RegexOptions.None, "??", true); + yield return ("\\?*?", RegexOptions.None, "??", true); + yield return ("(a*)*", RegexOptions.None, "aaa", true); + yield return ("((a*|b*))*", RegexOptions.None, "aaabbbaaa", true); + yield return ("(a?)*", RegexOptions.None, "aaa", true); + yield return ("((a)*(a)*)*", RegexOptions.None, "aaaa", true); + yield return ("(a|b)*", RegexOptions.None, "abab", true); + yield return ("(a|b)+", RegexOptions.None, "abab", true); + yield return ("(a|b|c)*", RegexOptions.None, "abcabc", true); + yield return ("(a|b|c)+", RegexOptions.None, "abcabc", true); + yield return ("(a|b)*c", RegexOptions.None, "ababc", true); + yield return ("a(a|b)*c", RegexOptions.None, "aababc", true); + yield return ("a(a|b)+c", RegexOptions.None, "aababc", true); + yield return ("a|b*", RegexOptions.None, "a", true); + yield return ("a|b*", RegexOptions.None, "b", true); + yield return ("a|b*", RegexOptions.None, "bb", true); + yield return ("a*a*", RegexOptions.None, "aaa", true); + yield return ("a*b*", RegexOptions.None, "aabb", true); + yield return ("(a*)*b", RegexOptions.None, "aaab", true); + yield return ("a*b*c*", RegexOptions.None, "aabbcc", true); + yield return ("a*b*", RegexOptions.None, "ab", true); + yield return ("a*b*", RegexOptions.None, "a", true); + yield return ("a*b*", RegexOptions.None, "b", true); + yield return ("a*b*", RegexOptions.None, "", true); + yield return ("a+", RegexOptions.None, "a", true); + yield return ("ab+", RegexOptions.None, "abb", true); + yield return ("aba+", RegexOptions.None, "abaa", true); + yield return ("a+a+", RegexOptions.None, "aa", true); + yield return ("a+a+", RegexOptions.None, "aaa", true); + yield return ("a+b+", RegexOptions.None, "ab", true); + yield return ("a+b+", RegexOptions.None, "aabb", true); + yield return ("(a+|b)+", RegexOptions.None, "aabb", true); + yield return ("(a+|b+)*", RegexOptions.None, "aabb", true); + yield return ("a?", RegexOptions.None, "a", true); + yield return ("a?", RegexOptions.None, "", true); + yield return ("ab?", RegexOptions.None, "a", true); + yield return ("ab?", RegexOptions.None, "ab", true); + yield return ("ab?a", RegexOptions.None, "aba", true); + yield return ("ab?a", RegexOptions.None, "aa", true); + yield return ("a?b?", RegexOptions.None, "ab", true); + yield return ("a?b?", RegexOptions.None, "a", true); + yield return ("a?b?", RegexOptions.None, "b", true); + yield return ("a?b?", RegexOptions.None, "", true); + yield return ("a??b??", RegexOptions.None, "ab", true); + yield return ("a??b??", RegexOptions.None, "a", true); + yield return ("a??b??", RegexOptions.None, "b", true); + yield return ("a??b??", RegexOptions.None, "", true); + yield return ("\\(a\\)", RegexOptions.None, "(a)", true); + yield return ("a\\*b", RegexOptions.None, "a*b", true); + yield return ("a\\*b*", RegexOptions.None, "a*bbb", true); + yield return ("\\\\", RegexOptions.None, "\\", true); + yield return ("\\\\\\\\", RegexOptions.None, "\\\\", true); + yield return ("\\w", RegexOptions.None, "a", true); + yield return ("\\w*", RegexOptions.None, "abc123", true); + yield return ("\\w+", RegexOptions.None, "abc123", true); + yield return ("\\w+", RegexOptions.None, "abc_123", true); + yield return ("\\d", RegexOptions.None, "1", true); + yield return ("\\d*", RegexOptions.None, "123", true); + yield return ("\\d+", RegexOptions.None, "123", true); + yield return ("\\d+", RegexOptions.None, "123abc", true); + yield return ("\\d", RegexOptions.None, "۲", true); + yield return ("\\s", RegexOptions.None, " ", true); + yield return ("\\s*", RegexOptions.None, " ", true); + yield return ("\\s*", RegexOptions.None, " \t\r", true); + yield return ("\\s+", RegexOptions.None, " ", true); + yield return ("\\s+", RegexOptions.None, " \t\n", true); + yield return ("\\s", RegexOptions.None, "\u0020", true); + yield return ("\\s", RegexOptions.None, "\u2028", true); + yield return ("\\W", RegexOptions.None, "!", true); + yield return ("\\W+", RegexOptions.None, "!@#", true); + yield return ("\\D", RegexOptions.None, "a", true); + yield return ("\\D", RegexOptions.None, "⅕", true); + yield return ("\\D+", RegexOptions.None, "abc", true); + yield return ("\\D+", RegexOptions.None, "!@#", true); + yield return ("\\S", RegexOptions.None, "a", true); + yield return ("\\S+", RegexOptions.None, "abc", true); + yield return ("[abc]", RegexOptions.None, "a", true); + yield return ("[abc]", RegexOptions.None, "b", true); + yield return ("[abc]", RegexOptions.None, "c", true); + yield return ("[abc]", RegexOptions.None, "d", false); + yield return ("[a-z]", RegexOptions.None, "a", true); + yield return ("[a-z]", RegexOptions.None, "z", true); + yield return ("[a-z]", RegexOptions.None, "A", false); + yield return ("[a-z]+", RegexOptions.None, "abc", true); + yield return ("[0-9]+", RegexOptions.None, "123", true); + yield return ("[^abc]", RegexOptions.None, "d", true); + yield return ("[^abc]", RegexOptions.None, "a", false); + yield return ("[^a-z]", RegexOptions.None, "1", true); + yield return ("a{3}", RegexOptions.None, "aaa", true); + yield return ("a{3}", RegexOptions.None, "aa", false); + yield return ("a{3}", RegexOptions.None, "aaaa", true); + yield return ("a{2,4}", RegexOptions.None, "aa", true); + yield return ("a{2,4}", RegexOptions.None, "aaa", true); + yield return ("a{2,4}", RegexOptions.None, "aaaa", true); + yield return ("a{2,4}", RegexOptions.None, "a", false); + yield return ("a{2,4}", RegexOptions.None, "aaaaa", true); + yield return ("a{2,}", RegexOptions.None, "aa", true); + yield return ("a{2,}", RegexOptions.None, "aaa", true); + yield return ("a{2,}", RegexOptions.None, "aaaa", true); + yield return ("a{2,}", RegexOptions.None, "a", false); + yield return ("(?:ab)+", RegexOptions.None, "ab", true); + yield return ("(?:ab)+", RegexOptions.None, "abab", true); + yield return ("(?:ab)+", RegexOptions.None, "ababab", true); + yield return ("(?:ab)+", RegexOptions.None, "a", false); + yield return ("a*?", RegexOptions.None, "aaa", true); + yield return ("a??", RegexOptions.None, "aaa", true); + yield return ("a{2,4}?", RegexOptions.None, "aaa", true); + yield return ("(a*)*?b", RegexOptions.None, "aaab", true); + yield return ("(a*?)*b", RegexOptions.None, "aaab", true); + yield return ("abc$", RegexOptions.None, "abcz", false); + yield return ("^abc$", RegexOptions.None, "abcz", false); + yield return ("^abc$", RegexOptions.None, "zabc", false); + yield return ("\\b", RegexOptions.None, "a", true); + yield return ("\\b", RegexOptions.None, " a", true); + yield return ("\\b", RegexOptions.None, "a ", true); + yield return ("\\B", RegexOptions.None, "ab", true); + yield return (".", RegexOptions.None, "a", true); + yield return (".", RegexOptions.None, "1", true); + yield return (".", RegexOptions.None, "!", true); + yield return (".", RegexOptions.None, "\n", false); + yield return (".+", RegexOptions.None, "abc", true); + yield return ("(a)", RegexOptions.None, "a", true); + yield return ("(a)(b)", RegexOptions.None, "ab", true); + yield return ("(a)|(b)", RegexOptions.None, "a", true); + yield return ("(a)|(b)", RegexOptions.None, "b", true); + yield return ("(?a)", RegexOptions.None, "a", true); + yield return ("(?a)(?b)", RegexOptions.None, "ab", true); + + // Lookahead and lookbehind are not supported by NonBacktracking engine + if (engine != RegexEngine.NonBacktracking) + { + yield return ("a(?=b)\\w", RegexOptions.None, "ab", true); + yield return ("a(?=c)\\w", RegexOptions.None, "ab", false); + yield return ("\\w(?<=a)b", RegexOptions.None, "ab", true); + yield return ("\\w(?<=c)b", RegexOptions.None, "ab", false); + yield return ("a(?!c)\\w", RegexOptions.None, "ab", true); + yield return ("a(?!b)\\w", RegexOptions.None, "ab", false); + yield return ("\\w(? Date: Fri, 17 Oct 2025 14:50:00 +0000 Subject: [PATCH 7/7] Remove temporary test file Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- .../FunctionalTests/RegexNimTests_refined.cs | 217 ------------------ 1 file changed, 217 deletions(-) delete mode 100644 src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests_refined.cs diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests_refined.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests_refined.cs deleted file mode 100644 index 6043605b745dfd..00000000000000 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexNimTests_refined.cs +++ /dev/null @@ -1,217 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using Xunit; - -namespace System.Text.RegularExpressions.Tests -{ - /// - /// These tests were ported from https://github.com/nitely/nim-regex/blob/master/tests/tests.nim - /// in order to increase .NET's test coverage. You can find the relevant repo license in this folder's THIRD-PARTY-NOTICES.TXT file. - /// - public class RegexNimTests - { - public static IEnumerable NimTestData() - { - foreach (RegexEngine engine in RegexHelpers.AvailableEngines) - { - (string pattern, RegexOptions options, string input, bool expectedSuccess)[] cases = NimTestData_Cases(engine).ToArray(); - Regex[] regexes = RegexHelpers.GetRegexes(engine, cases.Select(c => (c.pattern, (CultureInfo?)null, (RegexOptions?)c.options, (TimeSpan?)null)).ToArray()); - for (int i = 0; i < regexes.Length; i++) - { - yield return new object[] { regexes[i], cases[i].input, cases[i].expectedSuccess }; - } - } - } - - public static IEnumerable<(string Pattern, RegexOptions options, string Input, bool ExpectedSuccess)> NimTestData_Cases(RegexEngine engine) - { - yield return ("", RegexOptions.None, "", true); - yield return ("(a)b", RegexOptions.None, "ab", true); - yield return ("(a)*", RegexOptions.None, "aa", true); - yield return ("((a)*b)", RegexOptions.None, "aab", true); - yield return ("a(b|c)*d", RegexOptions.None, "abbbbccccd", true); - yield return ("((a)*(b)*)", RegexOptions.None, "abbb", true); - yield return ("((a(b)*)*(b)*)", RegexOptions.None, "abbb", true); - yield return ("a|b", RegexOptions.None, "a", true); - yield return ("a|b", RegexOptions.None, "b", true); - yield return ("a(b|c)*d", RegexOptions.None, "ab", false); - yield return ("b", RegexOptions.None, "a", false); - yield return ("\\s\".*\"\\s", RegexOptions.None, " \"word\" ", true); - yield return ("\\**", RegexOptions.None, "**", true); - yield return ("\\++", RegexOptions.None, "++", true); - yield return ("\\?+", RegexOptions.None, "??", true); - yield return ("\\?*", RegexOptions.None, "??", true); - yield return ("\\??", RegexOptions.None, "?", true); - yield return ("\\???", RegexOptions.None, "?", true); - yield return ("\\**?", RegexOptions.None, "**", true); - yield return ("\\++?", RegexOptions.None, "++", true); - yield return ("\\?+?", RegexOptions.None, "??", true); - yield return ("\\?*?", RegexOptions.None, "??", true); - yield return ("(a*)*", RegexOptions.None, "aaa", true); - yield return ("((a*|b*))*", RegexOptions.None, "aaabbbaaa", true); - yield return ("(a?)*", RegexOptions.None, "aaa", true); - yield return ("((a)*(a)*)*", RegexOptions.None, "aaaa", true); - yield return ("(a|b)*", RegexOptions.None, "abab", true); - yield return ("(a|b)+", RegexOptions.None, "abab", true); - yield return ("(a|b|c)*", RegexOptions.None, "abcabc", true); - yield return ("(a|b|c)+", RegexOptions.None, "abcabc", true); - yield return ("(a|b)*c", RegexOptions.None, "ababc", true); - yield return ("a(a|b)*c", RegexOptions.None, "aababc", true); - yield return ("a(a|b)+c", RegexOptions.None, "aababc", true); - yield return ("a|b*", RegexOptions.None, "a", true); - yield return ("a|b*", RegexOptions.None, "b", true); - yield return ("a|b*", RegexOptions.None, "bb", true); - yield return ("a*a*", RegexOptions.None, "aaa", true); - yield return ("a*b*", RegexOptions.None, "aabb", true); - yield return ("(a*)*b", RegexOptions.None, "aaab", true); - yield return ("a*b*c*", RegexOptions.None, "aabbcc", true); - yield return ("a*b*", RegexOptions.None, "ab", true); - yield return ("a*b*", RegexOptions.None, "a", true); - yield return ("a*b*", RegexOptions.None, "b", true); - yield return ("a*b*", RegexOptions.None, "", true); - yield return ("a+", RegexOptions.None, "a", true); - yield return ("ab+", RegexOptions.None, "abb", true); - yield return ("aba+", RegexOptions.None, "abaa", true); - yield return ("a+a+", RegexOptions.None, "aa", true); - yield return ("a+a+", RegexOptions.None, "aaa", true); - yield return ("a+b+", RegexOptions.None, "ab", true); - yield return ("a+b+", RegexOptions.None, "aabb", true); - yield return ("(a+|b)+", RegexOptions.None, "aabb", true); - yield return ("(a+|b+)*", RegexOptions.None, "aabb", true); - yield return ("a?", RegexOptions.None, "a", true); - yield return ("a?", RegexOptions.None, "", true); - yield return ("ab?", RegexOptions.None, "a", true); - yield return ("ab?", RegexOptions.None, "ab", true); - yield return ("ab?a", RegexOptions.None, "aba", true); - yield return ("ab?a", RegexOptions.None, "aa", true); - yield return ("a?b?", RegexOptions.None, "ab", true); - yield return ("a?b?", RegexOptions.None, "a", true); - yield return ("a?b?", RegexOptions.None, "b", true); - yield return ("a?b?", RegexOptions.None, "", true); - yield return ("a??b??", RegexOptions.None, "ab", true); - yield return ("a??b??", RegexOptions.None, "a", true); - yield return ("a??b??", RegexOptions.None, "b", true); - yield return ("a??b??", RegexOptions.None, "", true); - yield return ("\\(a\\)", RegexOptions.None, "(a)", true); - yield return ("a\\*b", RegexOptions.None, "a*b", true); - yield return ("a\\*b*", RegexOptions.None, "a*bbb", true); - yield return ("\\\\", RegexOptions.None, "\\", true); - yield return ("\\\\\\\\", RegexOptions.None, "\\\\", true); - yield return ("\\w", RegexOptions.None, "a", true); - yield return ("\\w*", RegexOptions.None, "abc123", true); - yield return ("\\w+", RegexOptions.None, "abc123", true); - yield return ("\\w+", RegexOptions.None, "abc_123", true); - yield return ("\\d", RegexOptions.None, "1", true); - yield return ("\\d*", RegexOptions.None, "123", true); - yield return ("\\d+", RegexOptions.None, "123", true); - yield return ("\\d+", RegexOptions.None, "123abc", true); - yield return ("\\d", RegexOptions.None, "۲", true); - yield return ("\\s", RegexOptions.None, " ", true); - yield return ("\\s*", RegexOptions.None, " ", true); - yield return ("\\s*", RegexOptions.None, " \t\r", true); - yield return ("\\s+", RegexOptions.None, " ", true); - yield return ("\\s+", RegexOptions.None, " \t\n", true); - yield return ("\\s", RegexOptions.None, "\u0020", true); - yield return ("\\s", RegexOptions.None, "\u2028", true); - yield return ("\\W", RegexOptions.None, "!", true); - yield return ("\\W+", RegexOptions.None, "!@#", true); - yield return ("\\D", RegexOptions.None, "a", true); - yield return ("\\D", RegexOptions.None, "⅕", true); - yield return ("\\D+", RegexOptions.None, "abc", true); - yield return ("\\D+", RegexOptions.None, "!@#", true); - yield return ("\\S", RegexOptions.None, "a", true); - yield return ("\\S+", RegexOptions.None, "abc", true); - yield return ("[abc]", RegexOptions.None, "a", true); - yield return ("[abc]", RegexOptions.None, "b", true); - yield return ("[abc]", RegexOptions.None, "c", true); - yield return ("[abc]", RegexOptions.None, "d", false); - yield return ("[a-z]", RegexOptions.None, "a", true); - yield return ("[a-z]", RegexOptions.None, "z", true); - yield return ("[a-z]", RegexOptions.None, "A", false); - yield return ("[a-z]+", RegexOptions.None, "abc", true); - yield return ("[0-9]+", RegexOptions.None, "123", true); - yield return ("[^abc]", RegexOptions.None, "d", true); - yield return ("[^abc]", RegexOptions.None, "a", false); - yield return ("[^a-z]", RegexOptions.None, "1", true); - yield return ("a{3}", RegexOptions.None, "aaa", true); - yield return ("a{3}", RegexOptions.None, "aa", false); - yield return ("a{3}", RegexOptions.None, "aaaa", true); - yield return ("a{2,4}", RegexOptions.None, "aa", true); - yield return ("a{2,4}", RegexOptions.None, "aaa", true); - yield return ("a{2,4}", RegexOptions.None, "aaaa", true); - yield return ("a{2,4}", RegexOptions.None, "a", false); - yield return ("a{2,4}", RegexOptions.None, "aaaaa", true); - yield return ("a{2,}", RegexOptions.None, "aa", true); - yield return ("a{2,}", RegexOptions.None, "aaa", true); - yield return ("a{2,}", RegexOptions.None, "aaaa", true); - yield return ("a{2,}", RegexOptions.None, "a", false); - yield return ("(?:ab)+", RegexOptions.None, "ab", true); - yield return ("(?:ab)+", RegexOptions.None, "abab", true); - yield return ("(?:ab)+", RegexOptions.None, "ababab", true); - yield return ("(?:ab)+", RegexOptions.None, "a", false); - yield return ("a*?", RegexOptions.None, "aaa", true); - yield return ("a??", RegexOptions.None, "aaa", true); - yield return ("a{2,4}?", RegexOptions.None, "aaa", true); - yield return ("(a*)*?b", RegexOptions.None, "aaab", true); - yield return ("(a*?)*b", RegexOptions.None, "aaab", true); - yield return ("abc$", RegexOptions.None, "abcz", false); - yield return ("^abc$", RegexOptions.None, "abcz", false); - yield return ("^abc$", RegexOptions.None, "zabc", false); - yield return ("\\b", RegexOptions.None, "a", true); - yield return ("\\b", RegexOptions.None, " a", true); - yield return ("\\b", RegexOptions.None, "a ", true); - yield return ("\\B", RegexOptions.None, "ab", true); - yield return (".", RegexOptions.None, "a", true); - yield return (".", RegexOptions.None, "1", true); - yield return (".", RegexOptions.None, "!", true); - yield return (".", RegexOptions.None, "\n", false); - yield return (".+", RegexOptions.None, "abc", true); - yield return ("(a)", RegexOptions.None, "a", true); - yield return ("(a)(b)", RegexOptions.None, "ab", true); - yield return ("(a)|(b)", RegexOptions.None, "a", true); - yield return ("(a)|(b)", RegexOptions.None, "b", true); - yield return ("(?a)", RegexOptions.None, "a", true); - yield return ("(?a)(?b)", RegexOptions.None, "ab", true); - - // Lookahead and lookbehind are not supported by NonBacktracking engine - if (engine != RegexEngine.NonBacktracking) - { - yield return ("a(?=b)\\w", RegexOptions.None, "ab", true); - yield return ("a(?=c)\\w", RegexOptions.None, "ab", false); - yield return ("\\w(?<=a)b", RegexOptions.None, "ab", true); - yield return ("\\w(?<=c)b", RegexOptions.None, "ab", false); - yield return ("a(?!c)\\w", RegexOptions.None, "ab", true); - yield return ("a(?!b)\\w", RegexOptions.None, "ab", false); - yield return ("\\w(?