16

我正在用 C# 编写各种 Telnet 客户端,我必须解析的部分内容是 ANSI/VT100 转义序列,特别是那些用于颜色和格式的转义序列(详见此处)。

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

    
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

4 回答 4

4

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

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

如果是这样,您应该会看到它的运行速度提高了〜两倍……

于 2008-09-09T21:36:28.560 回答
3

#1 较慢的原因是 [\d;]+ 是一个贪婪的量词。使用 +? 或者 *?将进行惰性量化。有关详细信息,请参阅MSDN - 量词

您可能想尝试:

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

这对你来说可能更快。

于 2008-08-07T16:24:02.570 回答
1

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

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

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

于 2008-08-07T15:57:16.133 回答
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.]
于 2008-09-17T15:31:46.340 回答