我们有一个场景需要我们解析大量电子邮件(纯文本),每个电子邮件“类型”都是针对不同平台运行的脚本的结果。有些是制表符分隔的,有些是空格分隔的,有些是我们还不知道的。
我们将来也需要支持更多的“格式”。
我们是否使用以下方法寻求解决方案:
- 正则表达式
- 简单的字符串搜索(使用 string.IndexOf 等)
- 莱克斯/雅克
- 其他
整体解决方案将在 C# 2.0(希望是 3.5)中开发
我们有一个场景需要我们解析大量电子邮件(纯文本),每个电子邮件“类型”都是针对不同平台运行的脚本的结果。有些是制表符分隔的,有些是空格分隔的,有些是我们还不知道的。
我们将来也需要支持更多的“格式”。
我们是否使用以下方法寻求解决方案:
整体解决方案将在 C# 2.0(希望是 3.5)中开发
正则表达式。
正则表达式几乎可以解决世界和平以外的所有问题。好吧,也许世界和平也是如此。
您所说的三个解决方案都涵盖了非常不同的需求。
手动解析(简单的文本搜索)是最灵活和适应性最强的,但是,由于所需的解析更加复杂,它很快就变成了真正的麻烦。
正则表达式是一个中间地带,可能是你最好的选择。它们功能强大且灵活,因为您可以自己从调用不同正则表达式的代码中添加更多逻辑。这里的主要缺点是速度。
Lex/Yacc实际上只适用于非常复杂、可预测的语法,并且缺乏很多编译后的灵活性。您不能在中间解析中轻松更改解析器,实际上您可以,但它太重了,您最好使用正则表达式。
我知道这是一个陈词滥调的答案,这一切都归结为您的确切需求,但根据您所说的,我个人可能会选择一袋正则表达式。
作为替代方案,正如 Vaibhav 指出的那样,如果您可能会出现几种不同的情况,并且您可以轻松检测到哪种情况即将到来,您可以制作一个插件系统来选择正确的算法,而这些算法都可能非常不同,一种在尖锐的情况下使用 Lex/Yacc,另一种在更简单的情况下使用 IndexOf 和正则表达式。
无论您使用哪种类型的字符串解析,您都可能应该拥有一个可插拔系统。因此,该系统根据电子邮件的类型调用正确的“插件”来解析它。
您必须将解决方案设计为可更新的,以便在出现未知情况时处理它们。为解析器创建一个接口,其中不仅包含用于解析电子邮件并以标准格式返回结果的方法,还包含用于检查电子邮件以确定解析器是否会执行的方法。
在您的配置中,确定您希望使用的解析器类型,设置其配置选项,以及确定解析器是否起作用的标识符的配置。通过程序集限定名称命名解析器,以便即使没有指向它们的程序集的静态链接,也可以在运行时实例化类型。
标识符也可以实现一个接口,因此您可以创建不同的类型来检查不同的事物。例如,您可以创建一个正则表达式标识符,用于解析电子邮件以查找特定模式。确保为标识符提供尽可能多的信息,以便它可以根据地址和电子邮件内容等做出决定。
当您已知的解析器无法处理作业时,请创建一个新的 DLL,该 DLL 具有实现解析器和标识符接口的类型,这些接口可以处理该作业并将它们放在您的 bin 目录中。
这取决于你在解析什么。对于 Regex 无法处理的任何内容,我一直在使用ANTLR。在你第一次进入递归下降解析之前,我会研究它们是如何工作的,然后再尝试使用这样的框架。如果您订阅了 MSDN 杂志,请查看 2008 年 2 月的问题,那里有一篇关于从头开始编写的文章。
一旦你理解了,学习 ANTLR 就会容易很多。还有其他框架,但 ANTLR 似乎拥有最多的社区支持和公共文档。作者还发表了The Definitive ANTLR Reference: Building Domain-Specific Languages。
正则表达式可能是你最好的选择、尝试和证明。另外可以编译正则表达式。
最好的选择是 RegEx,因为它提供了比任何其他选项更大程度的灵活性。
虽然您可以IndexOf
用来处理某些事情,但您可能很快就会发现自己编写的代码如下所示:
if(s.IndexOf("search1")>-1 || s.IndexOf("search2")>-1 ||...
这可以在一个 RegEx 语句中处理。此外,还有很多地方,例如RegExLib.com,您可以在其中找到共享正则表达式来解决问题的人。
@Coincoin 已经覆盖了基础;我只想补充一点,使用正则表达式特别容易得到难以阅读、难以维护的代码。正则表达式是一种功能强大且非常紧凑的语言,所以它经常这样。
在正则表达式中使用空格和注释可以大大简化正则表达式的维护。Eric Gunnerson 让我想到了这个想法。这是一个例子。
使用 PCRE。所有其他答案都只是第二好。
您提供的信息很少,我会选择正则表达式。
但是你想要解析什么样的信息以及你想要做什么可能会改变对 Lex/Yacc 的决定。
但看起来您已经下定决心使用字符串搜索 :)