痛苦地减慢正则表达式

时间:2011-06-27 15:31:33

标签: c# regex parsing

我正在尝试解析看起来像这样的格式化电子邮件:

From: Mr. Bob Simon Jones
Email: moo@cows.com
Comments: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris hendrerit, nibh a  tristique malesuada, tellus nibh pharetra mauris, id tincidunt lacus turpis vel risus. 
Vestibulum laoreet venenatis mauris sit amet suscipit. Cras vel pharetra nisl. Suspendisse venenatis ante quis tellus luctus id ornare sem pretium. Cras sodales tristique mauris sagittis ullamcorper. 
Ut sit amet urna magna. Nullam et odio sit amet mauris tempus egestas. Donec eget risus nec lectus adipiscing convallis. Pellentesque in velit enim. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi quis ante diam. Etiam rhoncus leo vulputate ligula luctus volutpat. Praesent luctus, justo eget auctor viverra, diam turpis fringilla elit, non commodo massa arcu et eros. Cras elementum faucibus elit, sollicitudin luctus mi dictum a.
Address: First line, Second Line, Third line pe2 8pd, Fourth Line
Date of Visit: 25/06/2011

我有一个正则表达式,如果这是唯一存在的文本,但是当它加载垃圾文本后变得非常慢,当在.NET应用程序中运行时它似乎根本没有完成。

正则表达式为:

.*From: (?<title>Mrs\.|Mr\.|Miss\.|Ms\.) (?<firstName>(\w| )*)(?<=. )(?<surname>(\w| )*)\s*
Email: (?<email>.*)\s*
Comments: (?<comments>(.|\s)*)\s*
Address: (?<address1>[^,]*), (?<address2>[^,]*), (?<address3>[^,]*),(?<address4>.*)\s*
Date of Visit: (?<dateOfVisit>\d\d/\d\d/\d\d\d\d).*

第一行找到最后一个名称栏,并将其用作姓氏和姓氏作为姓氏。

我认为它可能与此有关: http://www.regular-expressions.info/catastrophic.html

但我无法弄明白。想知道是否有人能指出我正确的方向?

感谢您的时间

3 个答案:

答案 0 :(得分:6)

让人惊讶。你想要立刻做太多事情。把它分成小块:

  1. 首先,获取每个字段的原始值。例如,From:Email:之间的所有内容都是名称。不要试图聪明 - 盲目。名字的内容并不重要 - 只是blob。

  2. 单独处理每个值并将其作为具有自己规则的不同值独立处理。有些可能是日期,有些可能是带有标题的名称等等。您可以编写一个小的,更简单的正则表达式来将这些更具体的数据分解为有意义的格式。

答案 1 :(得分:2)

这只是一个建议,但您是否尝试使用已编译的正则表达式? 以下是一些信息:http://en.csharp-online.net/CSharp_Regular_Expression_Recipes%E2%80%94Compiling_Regular_Expressions

答案 2 :(得分:0)

以下是正则表达式的一些增强功能,您可以测试一下吗?

From: (?<title>(?:Mrs|Mr|Miss|Ms)\.) (?<firstName>[\w ]*)(?<=. )(?<surname>[\w ]*)\s*
Email: (?<email>.*)\s*
Comments: (?<comments>(.*))\s*
Address: (?<address1>[^,]*), (?<address2>[^,]*), (?<address3>[^,]*),(?<address4>.*)\s*
Date of Visit: (?<dateOfVisit>\d{2}/\d{2}/\d{4})

将其与单行选项

一起使用