解析字符串的最佳方法是什么?

时间:2008-09-11 11:47:04

标签: c# email parsing projects-and-solutions

我们有一个场景要求我们解析大量的电子邮件(纯文本),每个电子邮件“类型”是脚本针对各种平台运行的结果。有些是制表符分隔的,有些是空格分隔的,有些是我们还不知道的。

我们将来也需要支持更多'格式'。

我们是否使用以下方式寻求解决方案:

  • 正则表达式
  • 只需字符串搜索(使用string.IndexOf等)
  • Lex / Yacc
  • 其他

整体解决方案将在C#2.0(希望3.5)

中开发

10 个答案:

答案 0 :(得分:5)

正则表达式。

除了世界和平之外,正则表达式几乎可以解决所有问题。也许世界和平也是如此。

答案 1 :(得分:4)

您说的三种解决方案都涵盖了非常不同的需求。

手动解析(简单文本搜索)是最灵活,最具适应性的,然而,由于所需的解析更加复杂,它很快就会成为一个真正的痛苦。

正则表达式是一个中间立场,这可能是你最好的选择。它们功能强大且灵活,您可以自己从调用不同正则表达式的代码中添加更多逻辑。主要的缺点是这里的速度。

Lex / Yacc 实际上只适用于非常复杂,可预测的语法,并且缺乏很多后编译灵活性。你不能轻易地在解析过程中更改解析器,实际上你可以,但它太重了,而你最好使用正则表达式。

我知道这是陈词滥调回答,这一切都归结为你的确切需求,但从你所说的,我个人可能会带着一袋正则表达式。

作为一个替代,正如Vaibhav所说,如果你有几种不同的情况可以出现并且你可以轻松地检测到哪一种,你可以制作一个选择正确算法的插件系统,这些算法可能都非常不同,一个在尖尖的情况下使用Lex / Yacc,另一个在较简单的情况下使用IndexOf和regex。

答案 2 :(得分:1)

无论您使用哪种类型的字符串解析,您都应该拥有可插拔系统。因此,该系统根据要解析它的电子邮件类型调用正确的“插件”。

答案 3 :(得分:1)

您必须将您的解决方案设计为可更新的,以便您可以在突然出现时处理未知情况。为解析器创建一个接口,该接口不仅包含解析电子邮件和以标准格式返回结果的方法,还包含检查电子邮件以确定解析器是否将执行的方法。

在您的配置中,确定您要使用的解析器的类型,设置其配置选项以及确定解析器是否将起作用的标识符的配置。按汇编限定名称命名解析器,以便即使没有到其程序集的静态链接,也可以在运行时实例化类型。

标识符也可以实现接口,因此您可以创建检查不同内容的不同类型。例如,您可以创建一个正则表达式标识符,该标识符解析特定模式的电子邮件。确保为标识符提供尽可能多的信息,以便它可以根据地址和电子邮件的内容做出决定。

当您的已知解析器无法处理作业时,请创建一个新的DLL,其类型实现可以处理作业的解析器和标识符接口,并将它们放在bin目录中。

答案 4 :(得分:1)

这取决于你要解析的内容。对于Regex可以处理的任何事情,我一直在使用ANTLR。在你第一次进入递归下降解析之前,我会在尝试使用像这样的框架之前研究它们是如何工作的。如果您订阅MSDN杂志,请查看2008年2月刊,其中有一篇关于从头开始编写文章的文章。

一旦你理解了,学习ANTLR会更容易。还有其他框架,但ANTLR似乎拥有最多的社区支持和公共文档。作者还发表了The Definitive ANTLR Reference: Building Domain-Specific Languages

答案 5 :(得分:0)

正则表达式可能是你打赌,尝试和证明。另外还可以编译正则表达式。

答案 6 :(得分:0)

最好的选择是RegEx,因为它提供了比任何其他选项更大程度的灵活性。

虽然您可以使用IndexOf来处理某些事情,但您很快就会发现自己编写的代码如下:

  

if(s.IndexOf("search1")>-1 || s.IndexOf("search2")>-1 ||...

可以在一个RegEx语句中处理。此外,还有很多像RegExLib.com这样的地方,你可以找到那些共享正则表达式来解决问题的人。

答案 7 :(得分:0)

@Coincoin涵盖了基础;我只是想用正则表达式添加它,特别容易得到难以阅读,难以维护的代码。正则表达式是一种功能强大且非常紧凑的语言,因此通常会如此。

在正则表达式中使用空格和注释可以大大简化维护正则表达式。 Eric Gunnerson让我接受了这个想法。这是an example

答案 8 :(得分:0)

使用PCRE。所有其他答案都是第二好的。

答案 9 :(得分:-1)

由于您提供的信息很少,我会选择Regex。

但是你要解析什么样的信息以及你想做什么会改变Lex / Yacc的决定......

但看起来你已经开始使用字符串搜索:)