优化我的正则表达式匹配的最佳方法是什么
本文关键字:最佳 方法 是什么 我的 正则表达式 优化 | 更新日期: 2023-09-27 18:35:37
我有一个带有文本框的应用程序。用户在此框中输入文本。
我在该文本框中的 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 regex = new Regex(rule);
if (regex.Match(text.Trim().ToLower()))
{
// matched rule is a variable
matchedRule = rule;
break;
}
}
}
我有大约 12 个字符串rules
,尽管这可能会有所不同。
一旦文本框中的文本长度大于 80 个字符,性能就会开始下降。 在 100 个字符后键入字母需要一秒钟才能显示。
如何优化?我应该在每次第三次 KeyUp 上匹配吗?我应该完全放弃 KeyUp 并每隔几秒钟自动匹配一次吗?
如何优化?我应该在每次第三次 KeyUp 上匹配吗?我应该完全放弃 KeyUp 并每隔几秒钟自动匹配一次吗?
我会选择第二个选项,即放弃KeyUp
并每隔几秒钟触发一次验证,或者更好的是,当TextBox
失去焦点时触发验证。
另一方面,我应该建议事先缓存正则表达式并编译它们,因为看起来您似乎在一遍又一遍地使用它们,换句话说,您应该将它们存储为已编译的正则表达式对象时,而不是将规则存储为该数组中的字符串添加或加载它们。
使用static
方法调用而不是每次都创建新对象, static
调用使用caching
功能:优化正则表达式性能,第一部分:使用正则表达式类和正则表达式对象。
这将是性能的重大改进,然后您可以提供正则表达式(规则)以查看是否可以在正则表达式中进行一些优化。
其他资源 :
- 优化正则表达式性能,第二部分:负责回溯
- 优化正则表达式性能,第 3 部分
在正则表达式级别将字符串组合为一个字符串将比代码中的 foreach 更快。将两个正则表达式合并为一个
如果您需要确定每个新符号的模式,并且您关心性能,那么最终状态机似乎是最佳选择......这是更难的方式。应为每个符号指定允许的下一个符号列表。如果可能的话,OnKeyUp你只需走下一个州。您将拥有输入文本当前匹配的模式数量。我可以找到一些有用的参考资料:
密克罗尼西亚联邦示例
家伙解释如何将正则表达式转换为 FSM
正则表达式 - FSM 转换讨论
您不需要每次都创建新的正则表达式对象。如果之前使用过,使用静态调用也将缓存模式(自 .Net 2 以来)。这是我如何重写它
matchedRule = Rules.FirstOrDefault( rule => Regex.IsMatch(text.Trim().ToLower(), rule))
;
鉴于您似乎正在匹配关键字,您能否对已编辑的文本的当前部分(即在光标附近)执行匹配?设计起来可能很棘手,尤其是对于粘贴或撤消等操作,但可以大幅提高性能。
预编译正则表达式(使用 RegexOptions.Compiled
)。另外,您能否通过扩展正则表达式来使Trim
和ToLower
变得多余?您为每个规则运行Trim
和ToLower
一次,即使您无法完全消除它们,效率也很低
您可以尝试使您的规则相互排斥 - 这应该会加快速度。我做了一个简短的测试:与以下内容匹配
"猫|汽车|驾驶室|盒子|气球|按钮"
可以这样写来加快
速度"ca(t|r|b)|b(ox|alloon|utton)"