2008-08-07 83 views
15

我正在編寫一個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);

這不僅工作,但實際上更快並減少了對文字渲染的影響。有人可以向正則表達式新手解釋,爲什麼? :)

回答

1

沒有做詳細的分析,我猜這是因爲問號更快。這些允許正則表達式是「懶惰的」,並在它們有足夠的匹配時立即停止,而不是檢查其餘的輸入是否匹配。

雖然我不完全滿意這個答案,因爲這主要適用於*或+之後的問號。如果我對輸入更加熟悉,那對我來說可能更有意義。

(同樣,對於代碼的格式,你可以選擇所有的代碼,然後按按Ctrl + ķ把它添加所需的四個空格。)

3

之所以#1是比較慢的那[\ d;] +是一個貪婪的量詞。使用+?要麼 *?會做懶惰的量化。有關更多信息,請參見MSDN - Quantifiers

您可能也想嘗試:

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

這可能會快一些適合你。

3

你真的想運行正則表達式兩次嗎?無需檢查(壞我)我還以爲,這將很好地工作:

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

如果是這樣,你應該看到它跑〜快兩倍......

+0

它現在想,這有一定道理,運行上沒有匹配行一個正則表達式是一樣的先運行一個檢查看看它是否匹配。你會得到相同的結果! – Nidonocu 2008-09-13 07:17:10

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.] 
+0

感謝您的回覆,當我毫無疑問地回過頭來查看代碼以獲取可能的改進時,我會隨時保留這個表達。 :)正如我發現的那樣,「較大」的正則表達式比較小的正則表達式更快。 – Nidonocu 2008-09-17 21:22:00