什么是优化我的正则表达式匹配的最佳方法

时间:2013-10-15 11:18:18

标签: 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 regex = new Regex(rule);
        if (regex.Match(text.Trim().ToLower()))
        {
            // matched rule is a variable
            matchedRule = rule;
            break;
        }
    }
}

我在rules中有大约12个字符串,尽管这可能会有所不同。

一旦文本框中文本的长度超过80个字符,性能就会开始下降。在100个字符后输入一个字母需要一秒钟才能显示出来。

如何优化此功能?我应该每隔3个KeyUp匹配一次吗?我应该完全放弃KeyUp并且每隔几秒钟自动匹配一次吗?

7 个答案:

答案 0 :(得分:4)

  

如何优化此功能?我应该每隔3个KeyUp匹配一次吗?我应该完全放弃KeyUp并且每隔几秒钟自动匹配一次吗?

我会选择第二个选项,即放弃KeyUp并每隔几秒触发一次验证,或者更好地在TextBox失去焦点时触发验证。

另一方面,我应该建议事先缓存正则表达式并编译它们,因为它似乎是一遍又一遍地使用它们,换句话说,而不是将规则存储为该数组中的字符串,你应该存储它们在添加或加载时作为编译的正则表达式对象。

答案 1 :(得分:1)

每次使用static方法调用而不是创建新对象, static 调用使用 caching 功能:{ {3}}

这将是性能的重大改进,然后您可以提供正则表达式(规则),以查看是否可以在正则表达式中进行某些优化。

其他资源:

答案 2 :(得分:0)

将字符串与Regex级别的字符串组合将比代码中的foreach更快。 Combining two Regex to one

答案 3 :(得分:0)

如果您需要每个新符号的模式确定,并且您关心性能,那么最终状态机似乎是最佳选择...... 这是一个更难的方式。您应该为允许的下一个符号的每个符号列表指定。 如果可能的话,OnKeyUp你只需走下一个州。并且您将拥有当前匹配的输入文本的模式数量。 一些有用的参考资料,我可以找到:

FSM example

Guy explaining how to convert Regex to FSM

Regex - FSM converting discussion

答案 4 :(得分:0)

每次都不需要创建新的正则表达式对象。如果之前使用(自.Net 2),也使用静态调用将缓存模式。以下是我将如何重写它

matchedRule = Rules.FirstOrDefault( rule => Regex.IsMatch(text.Trim().ToLower(), rule));

答案 5 :(得分:0)

鉴于您似乎匹配关键字,您是否可以仅对已编辑的文本的当前部分(即在光标附近)执行匹配?可能很难设计,特别是对于粘贴或撤消等操作,但可以获得巨大的性能提升。

答案 6 :(得分:-1)

预编译你的正则表达式(使用RegexOptions.Compiled)。另外,您可以通过扩展正则表达式使TrimToLower多余吗?您为每条规则运行TrimToLower一次,即使您无法完全消除它们,效率也很低

你可以尝试让你的规则互相排斥 - 这应该加快速度。我做了一个简短的测试:匹配以下

  

“猫|汽车|驾驶室|盒|气球|键”

可以通过像这样编写来加速

  

“CA(T | R | B)| B(牛| alloon | utton)”