2013-07-09 17 views
1

我目前在我的代碼中使用正則表達式來從富文本文檔中獲取大字符串。正則表達式查找任何嵌入式圖像並將其解析爲可轉換爲LinkedResource的字節數組。我需要將RTF從我的應用程序中的RichTextBox轉換爲有效的HTML文檔,然後轉換爲可以自動發送的MIME編碼消息。提高大字符串正則表達式的性能

正則表達式的問題在於,圖像的字符串部分非常大,所以我覺得正則表達式試圖匹配整個字符串中的許多可能性,而實際上,我只需要查看在該部分的開頭和結尾。下面的正則表達式作爲可選子句包含在較大的正則表達式中,如someRegexStringA + "|" + imageRegexString + "|" + "someRegexStringB"

我該怎麼做才能確保在較大的字符串中檢查較少,以便在解析大量圖像數據時我的應用程序不會凍結?

// The Regex itself 
private static string imageRegexString = @"(?<imageCheck>\\pict)"     // Look for the opening image tag 
             + @"(?:\\picwgoal(?<widthNumber>[0-9]+))" // Read the size of the image's width 
             + @"(?:\\pichgoal(?<heightNumber>[0-9]+))" // Read the size of the image's height 
             + @"(?:\\pngblip(\r|\n))"     // The image is the newline after this portion of the opening tag and information 
             + @"(?<imageData>(.|\r|\n)+?)"    // Read the bitmap 
             + @"(?:}+)";        // Look for closing braces 

// The expression is compiled so it doesn't take as much time during runtime 
private static Regex myRegularExpression = new Regex(imageRegexString, RegexOptions.Compiled); 

// Iterate through each image in the document 
foreach(Match image in myRegularExpression.Matches(myDocument)) 
{ 
    // Read the image height and width 
    int imageWidth = int.Parse(image.Groups["widthNumber"].Value); 
    int imageHeight = int.Parse(image.Groups["heightNumber"].Value); 

    // Process the image 
    ProcessImageData(image.Groups["imageData"].Value); 
} 
+2

我不確定RTF是否爲常規語言,但有專門用於將RTF文檔解析爲DOM樹的庫。 http://sourceforge.net/projects/rtfdomparser/它應該會給你一個顯着的提升。 (注意:我沒有試過這個庫)。不過,使用正確的工具應該有所幫助。您可以嘗試在其他資源上搜索「RTF DOM解析C#」。 – Amy

+0

我認爲你應該放棄RegEx的使用,你能解析二進制模式下的RTF文件嗎? – alfdev

+0

不幸的是,由於法律原因和我的僱主,我無法使用外部庫。另外,我已經研究過自己做了類似的事情,儘管它有效,但大量的努力已經進入了當前的解析方法。 – winglerw28

回答

1

首先,我依稀記得有與富文本編輯器,可以導出爲HTML InfoPath表單 - 所以你可能想看看那個(雖然我們仍然有附加單獨的圖像)

至於你的模式:這是非常簡單,只有一個可疑行:

(?<imageData>(.|\r|\n)+?) 

這有幾個潛在的問題:

  • +?是懶惰的,並且長字符串導致很多回溯,這可能是低效的。
  • .|\r|\n也似乎相當低效。您可以使用SingleLine修飾符(或inline (?s:...))。
    順便提一下,. already matches \r
  • (.|\r|\n) - 這是一個捕獲組,與您在別處使用的(?:...)組不同。我懷疑這是殺死你 - 在.Net中,每個字符被作爲Capture保存在一個堆棧中。你不想那樣。

我的建議是,用possessive group,只是爲了安全起見:

(?<imageData>(?>[^}]+)) 

當然,也有可能的模式是緩慢的,因爲其他交替的:someRegexStringAsomeRegexStringB

+0

優秀的解釋,我沒有意識到SingleLine修飾符。另外,這也導致了我對正則表達式的誤解所產生的其他優化。謝謝! – winglerw28