C# 优化正则表达式匹配的最佳方法是什么
我有一个带有文本框的应用程序。用户在此框中输入文本 我在该文本框中的OnKeyUp事件中触发了以下函数C# 优化正则表达式匹配的最佳方法是什么,c#,regex,windows-phone-8,C#,Regex,Windows Phone 8,我有一个带有文本框的应用程序。用户在此框中输入文本 我在该文本框中的OnKeyUp事件中触发了以下函数 private void bxItemText_KeyUp(object sender, System.Windows.Input.KeyEventArgs e) { // rules is an array of regex strings foreach (string rule in rules) { Regex re
private void bxItemText_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
// rules is an array of regex strings
foreach (string rule in rules)
{
Regex regex = new Regex(rule);
if (regex.Match(text.Trim().ToLower()))
{
// matched rule is a variable
matchedRule = rule;
break;
}
}
}
我在规则中有大约12个字符串,尽管这可能有所不同
一旦我的文本框中的文本长度超过80个字符,性能就会开始下降。在100个字符后键入一个字母需要一秒钟才能显示出来
如何对此进行优化?我应该每三次按键匹配一次吗?我是否应该完全放弃键控,每隔几秒钟自动匹配一次
如何对此进行优化?我应该每三次按键匹配一次吗?我是否应该完全放弃键控,每隔几秒钟自动匹配一次
我会选择第二个选项,即放弃KeyUp
并每隔几秒钟触发一次验证,或者在TextBox
失去焦点时触发验证
另一方面,我应该建议预先缓存正则表达式并编译它们,因为您似乎在反复使用它们,换句话说,在添加或加载规则时,您应该将它们存储为已编译的正则表达式对象,而不是将规则存储为该数组中的字符串
如何对此进行优化?我应该每三次按键匹配一次吗?我是否应该完全放弃键控,每隔几秒钟自动匹配一次
我会选择第二个选项,即放弃KeyUp
并每隔几秒钟触发一次验证,或者在TextBox
失去焦点时触发验证
另一方面,我建议提前缓存正则表达式并编译它们,因为您似乎在反复使用它们,换句话说,不要将规则作为字符串存储在该数组中,添加或加载正则表达式对象时,应将其存储为已编译的正则表达式对象。预编译正则表达式(使用RegexOptions.compiled
)。另外,您可以通过扩展正则表达式使Trim
和ToLower
冗余吗?您为每个规则运行一次Trim
和ToLower
,即使无法完全消除它们,这也是低效的
你可以试着让你的规则相互排斥——这会加快事情的发展。我做了一个简短的测试:匹配以下内容
“猫|车|驾驶室|盒子|气球|按钮”
这样写可以加快速度
“ca(t | r | b)| b(ox | allon | utton)”
预编译正则表达式(使用RegexOptions.Compiled
)。另外,您可以通过扩展正则表达式使Trim
和ToLower
冗余吗?您为每个规则运行一次Trim
和ToLower
,即使无法完全消除它们,这也是低效的
你可以试着让你的规则相互排斥——这会加快事情的发展。我做了一个简短的测试:匹配以下内容
“猫|车|驾驶室|盒子|气球|按钮”
这样写可以加快速度
“ca(t | r | b)| b(ox | allon | utton)”
在正则表达式级别将字符串组合成一个字符串将比在代码中使用foreach更快。
在正则表达式级别将字符串组合成一个字符串将比在代码中使用foreach更快。
使用静态
方法调用,而不是每次创建新对象,静态
调用使用缓存
功能:
这将是性能上的一个重大改进,然后您可以提供您的正则表达式(规则),看看是否可以在正则表达式中进行一些优化
其他资源:
使用静态
方法调用,而不是每次创建新对象,静态
调用使用缓存
功能:
这将是性能上的一个重大改进,然后您可以提供您的正则表达式(规则),看看是否可以在正则表达式中进行一些优化
其他资源:
如果您需要为每个新符号确定模式,并且您关心性能,那么最终状态机似乎是最佳选择。。。
这是非常困难的方法。您应该为每个符号指定允许的下一个符号的列表。
如果可能的话,你只需进入下一个州。您将拥有当前匹配的输入文本的模式数量。
我可以找到一些有用的参考资料:
如果您需要为每个新符号确定模式,并且您关心性能,那么最终状态机似乎是最佳选择。。。
这是非常困难的方法。您应该为每个符号指定允许的下一个符号的列表。
如果可能的话,你只需进入下一个州。您将拥有当前匹配的输入文本的模式数量。
我可以找到一些有用的参考资料:
您不需要每次都创建一个新的正则表达式对象。如果以前使用过(从.Net 2开始),使用静态调用也会缓存该模式。下面是我将如何重写它
matchedRule=Rules.FirstOrDefault(rule=>Regex.IsMatch(text.Trim().ToLower(),rule))
您不需要每次都创建一个新的regex对象。如果以前使用过(从.Net 2开始),使用静态调用也会缓存该模式。下面是我将如何重写它
matchedRule=Rules.FirstOrDefault(rule=>Regex.IsMatch(text.Trim().ToLower(),rule))
鉴于您似乎正在匹配关键字,您是否可以仅对已编辑文本的当前部分(即光标附近)执行匹配?设计起来可能很棘手,特别是对于粘贴或撤消之类的操作,但会获得很大的性能提升。鉴于您似乎在匹配关键字,您是否可以只对当前部分执行匹配