通过多次调用Regex来优化性能.IsMatch用于大文本
本文关键字:IsMatch 性能 用于 文本 优化 调用 Regex | 更新日期: 2023-09-27 18:03:02
我有一个很长的文本(50-60 KB),我需要对它运行几个正则表达式(总共大约100条规则)。然而,这是如此之慢,它基本上不能工作。
我所做的只是围绕规则创建一个循环,其中每个规则执行一个Regex.IsMatch()
。
有办法优化这个吗?
每个规则所做的样例代码:
public class SomeRegexInterceptor : ValidatorBase
{
private readonly Regex _rgx = new Regex("some regex", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
public override void Intercept(string html, ValidationResultCollection collection)
{
if (!_rgx.IsMatch(html)) return;
/* do something irrelevant here */
}
}
关于使用Regex替换的最重要的事情是如何以及在哪里声明Regex。永远不要在循环中初始化Regex对象
创建一个静态类并添加public static readonly
Regex字段,RegexOptions.Compiled
标志集
然后,在需要的地方使用它们,例如使用MyRegexClass.LeadingWhitespace.Replace(str, string.Empty)
。
请注意,如果您需要使用Regex.Replace
,则不需要检查之前是否与Regex.IsMatch
匹配。
阅读并遵循。net框架中正则表达式最佳实践的建议,即:
- 考虑输入源
- 正确处理对象实例化
- 负责回溯
- 使用超时值
- 仅在必要时捕获
另外,考虑逐行处理文件,尽量避免使用正则表达式。
你能把你的规则合并成一个规则吗?例如:如果你正在为"aaa"做一个正则表达式,然后为"bbb"做一个正则表达式,合并成"aaa|bbb"可以极大地提高性能(而不是运行两个单独的正则表达式)。我以前以这种方式编程地组合了大量的正则表达式,它使性能产生了巨大的差异。
组合表达式
如果您有能力在运行规则之前完成工作,您可以将正则表达式与|
结合起来,并一次完成搜索。然后在你的规则中,你不像以前那样匿名检查匹配,而是根据组的名称。例如
>((?<Ex1>expression1)|(?<Ex2>expression2)|(?<Ex3>expression3))
规则关心组Ex1
,它检查这个组。关心Ex2
的规则检查Ex2
,以此类推。
此外,您可能会分析一组正则表达式并以某种方式对它们进行优化。这将是一个相当了不起的编程壮举,除非你做一些简单的事情,如消除重复。
缓存,缓存大小
另一个想法是缓存和编译所有的正则表达式一次,和改变Regex.CacheSize
的大小,看看它是否有帮助。文档说明默认值是15,但是您超过了这个值。
更多信息关于实例化和编译一次表达式的注释是有效的,即使是那个大的注释也是有效的。MSDN提供了其他建议