Regex vs Tryparse性能最佳

时间:2011-04-19 10:48:09

标签: c# asp.net regex performance tryparse

在我的ASP.net项目中,我需要为用户输入验证一些基本数据类型。数据类型类似于数字,十进制,日期时间等。

在性能方面,我应采取的最佳方法是什么?是由Regex.IsMatch()还是TryParse()执行?

提前致谢。

4 个答案:

答案 0 :(得分:9)

TryParseRegex.IsMatch用于两个根本不同的事情。 Regex.IsMatch会告诉您相关字符串是否与某个特定模式匹配。它返回是/否答案。 TryParse实际上会在可能的情况下转换值,并告诉您它是否成功。

除非您在制作正则表达式时非常小心,否则Regex.IsMatch会在true返回TryParse时返回false。例如,考虑解析byte的简单情况。使用TryParse,您有:

byte b;
bool isGood = byte.TryParse(myString, out b);

如果myString中的值介于0到255之间,则TryParse将返回true

现在,让我们试试Regex.IsMatch。让我们看看,正则表达式应该是什么?我们不能只说@"\d+"甚至@\d{1,3}"。指定格式变得非常困难。您必须处理前导0,前导和尾随空格,并允许255但不允许256

这只是为了解析一个3位数字。当您解析intlong时,规则会变得更加复杂。

正则表达式非常适合确定表单。在确定时,他们很糟糕。由于我们的标准数据类型都有限制,因此确定其值是确定数字是否有效的一部分。

你最好尽可能使用TryParse,如果只是为了省去尝试提出可靠的正则表达式进行验证的头痛。可能(我几乎可以肯定地说),任何本机类型的特定TryParse执行速度都比同等正则表达式快。

上面说过,我可能在这个答案上花了更多的时间,而不是你的网页在整个生命周期中花费的时间来执行你的TryParseRegex.IsMatch。在网站正在做的其他事情的背景下,执行这些事情的时间非常少,任何时候你花费在思考问题上都会浪费。

如果可以,请使用TryParse,因为它更容易。否则使用Regex

答案 1 :(得分:4)

正如其他人所说,回答这个问题的最佳方法是衡量它;)

    static void Main(string[] args)
    {

        List<double> meansFailedTryParse = new List<double>();
        List<double> meansFailedRegEx = new List<double>();
        List<double> meansSuccessTryParse = new List<double>();
        List<double> meansSuccessRegEx = new List<double>();


        for (int i = 0; i < 1000; i++)
        {


            string input = "123abc";

            int res;
            bool res2;
            var sw = Stopwatch.StartNew();
            res2 = Int32.TryParse(input, out res);
            sw.Stop();
            meansFailedTryParse.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + " try parse :" + sw.Elapsed.TotalMilliseconds);

            sw = Stopwatch.StartNew();
            res2 = Regex.IsMatch(input, @"^[0-9]*$");
            sw.Stop();
            meansFailedRegEx.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + "  Regex.IsMatch :" + sw.Elapsed.TotalMilliseconds);

            input = "123";
            sw = Stopwatch.StartNew();
            res2 = Int32.TryParse(input, out res);
            sw.Stop();
            meansSuccessTryParse.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + " try parse :" + sw.Elapsed.TotalMilliseconds);


            sw = Stopwatch.StartNew();
            res2 = Regex.IsMatch(input, @"^[0-9]*$");
            sw.Stop();
            meansSuccessRegEx.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + "  Regex.IsMatch :" + sw.Elapsed.TotalMilliseconds);
        }

        Console.WriteLine("Failed TryParse mean execution time     " + meansFailedTryParse.Average());
        Console.WriteLine("Failed Regex mean execution time        " + meansFailedRegEx.Average());

        Console.WriteLine("successful TryParse mean execution time " + meansSuccessTryParse.Average());
        Console.WriteLine("successful Regex mean execution time    " + meansSuccessRegEx.Average());
    }
}

答案 2 :(得分:4)

不要试图让正则表达式做任何事情。

有时,一个简单的正则表达式可以让你获得90%的胜利,并使它能够完成所需的一切,复杂性增长十倍或更多。

然后我经常发现最简单的解决方案是使用正则表达式检查表单,然后依靠好的旧代码进行值检查。

以日期为例,使用正则表达式检查日期格式的匹配项,然后使用捕获组检查各个值的值。

答案 3 :(得分:1)

我猜TryParse更快,但更重要的是,它更具表现力。

当您考虑所使用的每种数据类型的所有有效值时,正则表达式会非常难看。例如,对于DateTime,您必须确保月份在1到12之间,并且该日期在该特定月份的有效范围内。