【问题标题】:What's the best way of parsing strings? [closed]解析字符串的最佳方法是什么? [关闭]
【发布时间】:2008-09-11 11:47:03
【问题描述】:

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

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

    正则表达式。

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

    【讨论】:

    • 我听说 Regex 负责拆除柏林墙。
    • 他们确实应该停止在灾难片中使用核武器。
    • 正则表达式:生活中所有问题的原因和解决方案。
    【解决方案2】:

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

    手动解析(简单的文本搜索)是最灵活和适应性最强的,但是,由于所需的解析更加复杂,它很快就会成为真正的麻烦。

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

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

    我知道这是陈词滥调答案,这完全取决于您的确切需求,但根据您所说,我个人可能会选择一袋正则表达式。

    作为一种替代,正如 Vaibhav 指出的那样,如果您可能会出现几种不同的情况,并且您可以轻松检测到哪种情况即将到来,那么您可以制作一个选择正确算法的插件系统,并且这些算法都可能非常不同,一种在尖锐的情况下使用 Lex/Yacc,另一种在更简单的情况下使用 IndexOf 和正则表达式。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

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

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

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

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

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

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

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

              【讨论】:

                【解决方案8】:

                @Coincoin 已经覆盖了基础;我只想补充一点,使用正则表达式特别容易得到难以阅读、难以维护的代码。正则表达式是一种功能强大且非常紧凑的语言,因此它经常使用。

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

                【讨论】:

                  【解决方案9】:

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

                  【讨论】:

                  • 它可以让你进行不同类型的文本、正则表达式等搜索。它是一个编译库,可以让你在很多平台上做很多事情,并且已经过多年的测试。它可能会比您编写的实现快得多。
                  【解决方案10】:

                  您提供的信息很少,我会选择正则表达式。

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

                  但看起来您已经下定决心使用字符串搜索:)

                  【讨论】:

                    猜你喜欢
                    • 2012-07-28
                    • 2017-04-04
                    • 2011-09-05
                    • 1970-01-01
                    • 2011-03-13
                    • 2020-07-11
                    • 1970-01-01
                    • 1970-01-01
                    • 2020-03-14
                    相关资源
                    最近更新 更多