2013-07-09 89 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