2

我创建了一个演示应用程序来测试一些正则表达式的性能。我的第三个测试使用选项RightToLeft

似乎它加快了这个过程!为什么?它有什么作用?

这是我的测试应用程序:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        private const string IsRequestForDirectoryWithoutTrailingSlashRegex = @"^(?#Path:)(.*/)?(?#LastPart:)(?<!\.asmx|\.aspx/)([^./?#]+?)(?#QueryString:)(\?.*?)(?#Anchor:)?(#.*)?$";

        private static string[] Tests = new string[] {
            "http://localhost/manager/page.aspx",
            "http://localhost/manager/",
            "http://localhost/manager",
            "http://localhost/manager/?param=value",
            "http://localhost/manager/dir?param=value"
        };

        static void Main(string[] args)
        {
            Test1();
            Test2();
            Test3();
            Test4();

            Console.WriteLine();
            Console.ReadLine();
        }

        public static void Test1()
        {
            Regex regex = new Regex(IsRequestForDirectoryWithoutTrailingSlashRegex);
            DoWork("1", regex);
        }

        public static void Test2()
        {
            Regex regex = new Regex(IsRequestForDirectoryWithoutTrailingSlashRegex, RegexOptions.Compiled);
            DoWork("2", regex);
        }

        public static void Test3()
        {
            Regex regex = new Regex(IsRequestForDirectoryWithoutTrailingSlashRegex, RegexOptions.Compiled | RegexOptions.RightToLeft);
            DoWork("3", regex);
        }

        public static void Test4()
        {
            Regex regex = new Regex(IsRequestForDirectoryWithoutTrailingSlashRegex, RegexOptions.Compiled | RegexOptions.RightToLeft | RegexOptions.IgnoreCase);
            DoWork("4", regex);
        }
        static void DoWork(string name, Regex regex)
        {
            Stopwatch sp = new Stopwatch();
            sp.Start();

            for (int i = 0; i < 100000; i++)
            {
                foreach (string s in Tests)
                {
                    regex.IsMatch(s);
                }
            }

            foreach (string s in Tests)
            {
                Console.WriteLine(":" + s + ":" + regex.IsMatch(s).ToString());
            }

            sp.Stop();

            Console.WriteLine("Test " + name + ": " + sp.ElapsedTicks);
        }
    }
}
4

1 回答 1

1

RegexOptions.RightToLeft当您尝试匹配您希望在输入字符串末尾找到的模式时,这可能很有用,因为正如其文档所述:搜索来自右到左从输入字符串的最后一个字符开始从左到右,但正则表达式本身仍然从左到右应用。

您的正则表达式似乎正在寻找目录路径的尾部斜杠,因此这似乎是符合描述的情况。

尽管您的表达式正在寻找尾部斜杠,但这两个锚(^$)的存在使我的推理错误,因为无论从哪里开始,正则表达式都只能以一种可能的方式匹配。

我将继续寻找这背后的真正原因,但现在我将保持原样。

另一方面,表达式开头部分.*/之后的表达式(?#Path:)部分会消耗整个输入字符串,然后它每次都会递归返回以找到最后一个/,因此当进一步开始搜索时,可能不会有很多的回溯。

于 2013-10-07T12:40:37.090 回答