在我的 ASP.net 项目中,我需要验证用户输入的一些基本数据类型。数据类型有数字、十进制、日期时间等。
就性能而言,我应该采取的最佳方法是什么?是按Regex.IsMatch()
还是按TryParse()
?
提前致谢。
在我的 ASP.net 项目中,我需要验证用户输入的一些基本数据类型。数据类型有数字、十进制、日期时间等。
就性能而言,我应该采取的最佳方法是什么?是按Regex.IsMatch()
还是按TryParse()
?
提前致谢。
TryParse
并Regex.IsMatch
用于两个根本不同的事情。Regex.IsMatch
告诉您所讨论的字符串是否与某个特定模式匹配。它返回一个是/否的答案。TryParse
如果可能,实际转换该值,并告诉您它是否成功。
除非您在制作正则表达式时非常小心Regex.IsMatch
,否则可以 return true
when TryParse
will return false
。例如,考虑解析 a 的简单情况byte
。与TryParse
您一起:
byte b;
bool isGood = byte.TryParse(myString, out b);
如果 in 的值在myString
0 到 255 之间,TryParse
将返回true
.
现在,让我们尝试使用Regex.IsMatch
. 让我们看看,那个正则表达式应该是什么?我们不能只说@"\d+"
,甚至@\d{1,3}"
。指定格式成为一项非常困难的工作。您必须处理前导 0、前导和尾随空格,并允许255
但不允许256
.
这只是用于解析 3 位数字。当您解析int
or时,规则变得更加复杂long
。
正则表达式非常适合确定形式。他们在确定价值方面很糟糕。由于我们的标准数据类型都有限制,因此确定其值是确定数字是否有效的一部分。
你最好TryParse
尽可能使用,如果只是为了省去你试图提出一个可靠的正则表达式来进行验证的麻烦。很可能(我会说几乎可以肯定)TryParse
任何本机类型的特定执行都会比等效的正则表达式更快。
上面说,我在这个答案上花费的时间可能比您的网页在其整个生命周期中执行您的TryParse
或--total 所花费的时间更多。Regex.IsMatch
与您的网站正在执行的所有其他操作相比,执行这些操作的时间是如此之少,您花在思考问题上的任何时间都被浪费了。
TryParse
如果可以,请使用,因为它更容易。否则使用Regex
.
正如其他人所说,回答这个问题的最佳方法是衡量它;)
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());
}
}
不要试图让正则表达式做所有事情。
有时,一个简单的正则表达式可以让你完成 90% 的工作,并让它完成你需要的一切,复杂性会增长十倍或更多。
然后我经常发现最简单的解决方案是使用正则表达式检查表单,然后依靠良好的旧代码进行值检查。
以日期为例,使用正则表达式检查日期格式的匹配,然后使用捕获组检查各个值的值。
我猜 TryParse 更快,但更重要的是,它更具表现力。
当您考虑所使用的每种数据类型的所有有效值时,正则表达式可能会变得非常难看。例如,对于 DateTime,您必须确保月份在 1 到 12 之间,并且日期在该特定月份的有效范围内。