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

6
我们有一个场景需要解析大量的电子邮件(纯文本),每个电子邮件“类型”都是通过运行脚本针对各种平台得出的结果。有些是制表符分隔的,有些是空格分隔的,有些我们还不知道。
我们将来还需要支持更多的“格式”。
我们应该选择以下哪种方案:
- 正则表达式 - 简单的字符串搜索(使用string.IndexOf等) - Lex/Yacc - 其他
整体解决方案将在C# 2.0(希望是3.5)中开发。
10个回答

5

正则表达式。

正则表达式几乎可以解决所有问题,除了世界和平。嗯,也许连世界和平也能解决。


2
我听说正则表达式是推倒柏林墙的罪魁祸首。 - Robert Durgin
1
他们确实应该停止在灾难电影中使用核武器。 - Coincoin
1
正则表达式:生活中所有问题的根源和解决之道。 - Matthew King

4
你提到的三种解决方案每一种都涵盖了不同的需求。
手动解析(简单文本搜索)是最灵活和最适应性强的,但随着所需解析的复杂度增加,它很快就会变得非常麻烦。
正则表达式是中间地带,可能是你最好的选择。它们功能强大,同时也很灵活,因为你可以从调用不同正则表达式的代码中自己添加更多逻辑。主要缺点在于速度较慢。
Lex/Yacc只适用于非常复杂、可预测的语法,并且缺乏许多编译后的灵活性。你不能轻松地在解析过程中更改解析器,实际上你可以,但这太重了,最好使用正则表达式代替。
我知道这是一个陈词滥调的答案,但实际上它真的取决于你的确切需求,但根据你所说,我个人可能会选择一袋正则表达式。
作为另一种选择,正如Vaibhav指出的那样,如果你有几种不同的情况可能会出现,并且你可以轻松检测到哪一个正在发生,你可以制作一个插件系统,选择正确的算法,这些算法可以非常不同,一个使用Lex/Yacc在尖锐的情况下,另一个使用IndexOf和正则表达式处理更简单的情况。

1

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


1

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

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

标识符也可以实现接口,因此您可以创建检查不同内容的不同类型。例如,您可能会创建一个正则表达式标识符,该标识符解析特定模式的电子邮件。确保将尽可能多的信息提供给标识符,以便它可以对来自地址以及电子邮件内容等事项进行决策。

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


1

这要看您正在解析什么。 对于超出正则表达式处理范围的任何内容,我一直使用ANTLR。 在第一次尝试递归下降解析之前,建议了解其工作原理,然后再尝试使用此框架。如果您订阅MSDN杂志,请查看2008年2月号上关于从头编写递归下降解析的文章。

一旦您理解了基础知识,学习ANTLR就会变得更加容易。还有其他框架可用,但ANTLR似乎得到了最多的社区支持和公共文档。该作者还出版了The Definitive ANTLR Reference: Building Domain-Specific Languages


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

它让你可以进行不同类型的搜索,如文本、正则表达式等。它是一个编译库,可以在许多平台上完成许多任务,并经过多年测试。它可能比你自己编写的实现要快得多。 - Geek

0

正则表达式可能是您最好的选择,经过尝试和验证。此外,正则表达式可以编译。


0

你最好使用正则表达式,因为它提供了比其他选项更高的灵活性。

虽然你可以使用 IndexOf 来处理某些情况,但你可能很快会发现自己编写的代码像这样:

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

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


0

@Coincoin 已经涵盖了基本内容;我只是想补充说明,使用正则表达式很容易产生难以阅读和维护的代码。正则表达式是一种功能强大且非常紧凑的语言,所以通常是这样的。

在正则表达式中使用空格和注释可以大大提高其可维护性。Eric Gunnerson 启发了我这个想法。这里有一个例子。


-1

根据您提供的信息,我会选择使用正则表达式。

但是,如果您想要解析什么样的信息以及想要做什么将会改变使用 Lex/Yacc 的决定。

不过看起来您已经决定使用字符串搜索了 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接