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

时间:2008-08-07 15:43:11

标签: regex ansi

我正在用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);

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

4 个答案:

答案 0 :(得分:4)

你真的想要两次运行正则表达式吗?如果没有检查(坏我),我会认为这样做会很好:

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

如果确实如此,你应该看到它跑得快〜两倍......

答案 1 :(得分:3)

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

您可能想尝试:

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

对你来说这可能会更快。

答案 2 :(得分:1)

没有做详细的分析,我猜它因为问号而更快。这些允许正则表达式“懒惰”,并且只要它们足够匹配就停止,而不是检查输入的其余部分是否匹配。

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

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

答案 3 :(得分:1)

我不确定这对你正在做什么有帮助,但很久以前我写了一个正则表达式来解析ANSI图形文件。

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

它将返回每个代码以及与之关联的文本。

输入字符串:

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

结果:

[ [1, 32], m, This is bright green.]
[0, m, This is the default color.]