在我的ASP.net项目中,我需要为用户输入验证一些基本数据类型。数据类型类似于数字,十进制,日期时间等。
在性能方面,我应采取的最佳方法是什么?是由Regex.IsMatch()
还是TryParse()
执行?
提前致谢。
答案 0 :(得分:9)
TryParse
和Regex.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位数字。当您解析int
或long
时,规则会变得更加复杂。
正则表达式非常适合确定表单。在确定值时,他们很糟糕。由于我们的标准数据类型都有限制,因此确定其值是确定数字是否有效的一部分。
你最好尽可能使用TryParse
,如果只是为了省去尝试提出可靠的正则表达式进行验证的头痛。可能(我几乎可以肯定地说),任何本机类型的特定TryParse
执行速度都比同等正则表达式快。
上面说过,我可能在这个答案上花了更多的时间,而不是你的网页在整个生命周期中花费的时间来执行你的TryParse
或Regex.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之间,并且该日期在该特定月份的有效范围内。