为什么这个正则表达式更快?

我正在用C#编写一个Telnet客户端,我必须解析的一部分是ANSI / VT100转义序列,特别是那些用于颜色和格式化的转义序列(详细 here )。

我拥有的一种方法是找到所有代码并将其删除,因此,如果需要,我可以在不使用任何格式的情况下呈现文本:

    
public static string StripStringFormating(string formattedString)
{
    if (rTest.IsMatch(formattedString))
        return rTest.Replace(formattedString, string.Empty);
    else
        return formattedString;
}

我是新来的正则表达式,我被建议使用这个:

static Regex rText = new Regex(@"\e\[[\d;]+m", RegexOptions.Compiled);

但是,如果转义码由于服务器上的错误而不完整,则此操作失败。所以这是建议的,但我的朋友警告它可能会更慢(这也符合我可能会遇到的另一个条件(z)):

static Regex rTest = 
              new Regex(@"(\e(\[([\d;]*[mz]?))?)?", RegexOptions.Compiled);

这不仅工作,而且实际上更快,并减少了对文本渲染的影响。有人可以向正则表达式新手解释,为什么? :)

0

4 答案

如果不进行详细的分析,我会猜测由于问号而更快。这些允许正则表达式为“懒惰”,并在它们有足够的匹配时立即停止,而不是检查输入的其余部分是否匹配。

尽管我对此答案并不满意,因为这主要适用于*或+之后的问号。如果我对输入更加熟悉,那对我来说可能更有意义。

(另外,对于代码格式化,您可以选择所有代码,然后按 Ctrl + K 使其添加所需的四个空格。)

0
额外

你真的想要运行正则表达式两次吗?没有检查(坏我)我会认为这将工作得很好:

public static string StripStringFormating(string formattedString)
{    
    return rTest.Replace(formattedString, string.Empty);
}

如果是这样,你应该看到它运行〜两倍的速度...

0
额外
现在想想看,这样做是有道理的,在没有匹配的情况下运行正则表达式与首先运行检查以查看它是否匹配完全相同。你会得到相同的结果!
额外 作者 Nidonocu,

#1较慢的原因是[\ d;] +是一个贪婪的量词。使用+?要么 *?会做懒惰的量化。有关更多信息,请参阅 MSDN - 量词

你可能想尝试:

"(\e\[(\d{1,2};)*?[mz]?)?"

这对你来说可能会更快。

0
额外

我不确定这是否会对你正在处理的内容有所帮助,但是很久以前我写了一个正则表达式来解析ANSI图形文件。

(?s)(?:\e\[(?:(\d+);?)*([A-Za-z])(.*?))(?=\e\[|\z)

它会返回每个代码和与其关联的文本。

输入字符串:

[1;32mThis is bright green.[0m This is the default color.

结果:

[ [1, 32], m, This is bright green.]
[0, m, This is the default color.]
0
额外
感谢您的回复,当我毫无疑问地回过头来查看代码以寻求可能的改进时,我会保留这个表达。 :)正如我发现的那样,“较大”的正则表达式比较小的正则表达式更快。
额外 作者 Nidonocu,
我也对.NET中使用ANSI代码的任何事情感兴趣。我目前正在使用rails而不是.NET重做我的网站,但我总是很好奇人们如何能够利用.NET来解释ANSI。
额外 作者 lordscarlet,