Пример #1
0
        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;
            }
        }
Пример #2
0
        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>());
        }
Пример #3
0
        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 });
                }
            }
        }
Пример #4
0
        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, "" });
                }
            }
        }
Пример #5
0
        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         " });
                }
            }
        }
Пример #6
0
        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();
            }
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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" });
                }
            }
        }
Пример #10
0
        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);
                    }
                }
            }
        }
Пример #11
0
        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" } });
                }
            }
        }
Пример #12
0
        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),
                            }
                        });
                    }
                }
            }
        }
Пример #14
0
        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" } });
                    }
                }
            }
        }