【问题标题】:PCRE in Haskell - what, where, how?Haskell 中的 PCRE - 什么,在哪里,如何?
【发布时间】:2011-12-14 12:20:19
【问题描述】:

多年来,我一直在寻找一些关于 Haskell 正则表达式的文档或教程。 HaskellWiki page 上没有有用的信息。它只是给出了神秘的信息:

Documentation
Coming soonish.

有一个简短的blog post 我发现它很有帮助,但是它只处理 Posix 正则表达式,而不是 PCRE。

我已经使用 Posix 正则表达式几个星期了,我得出的结论是,我的任务需要 PCRE。

我的问题是我不知道在 Haskell 中从哪里开始使用 PCRE。我已经用 cabal 下载了regex-pcre-builtin,但我需要一个简单匹配程序示例来帮助我开始。

  • 是否可以实现多行匹配?
  • 我能否以这种格式取回匹配项:[(MatchOffset,MatchLength)]
  • 我还可以使用哪些其他格式恢复匹配项?

非常感谢您的帮助!

【问题讨论】:

    标签: regex haskell pcre


    【解决方案1】:

    想要在 Haskell 中使用 PCRE 风格的正则表达式时,有两个主要选项:

    • regex-pcre 使用与该博客文章中描述的相同界面(以及RWH,因为我认为是该博客文章的扩展版本);这可以选择使用pcre-less 进行扩展。 regex-pcre-builtin 似乎是它的预发布快照,可能不应该使用。

    • pcre-light 绑定到 PCRE 库。它不提供您所追求的返回类型,只提供所有匹配项(如果有)。 然而pcre-light-extras 包提供了一个MatchResult 类,您或许可以为其提供这样的实例。这可以使用regexqq 来增强,它允许您使用准引用来确保您的正则表达式模式类型检查;但是,它不适用于 GHC-7(除非有人接管维护它,否则它不会)。

    所以,假设你选择regex-pcre

    • 根据this的回答,是的。

    • 我想是的,通过MatchArray 类型(它返回一个数组,然后您可以从中取出列表)。

    • 请参阅here 了解正则表达式的所有可能结果。

    【讨论】:

    • 当我尝试这种方法进行多行匹配时,我收到了错误Not in scope 'compNewLine'。我认为它只适用于 Posix。
    • @NickBrunt compMultiline 或许那时?
    • pcre-light-extras 不是矛盾吗?
    • @mcandre:是的,我想最后两个词有点相互抵消......:p
    【解决方案2】:

    regexpr 是另一个 PCRE 风格的库,它是跨平台的并且可以快速上手。

    【讨论】:

      【解决方案3】:

      嗯,我写了很多 wiki 页面,可能写了“即将推出”。 regex-pcre 包是我使用 regex-base 接口对 PCRE 的包装,其中 regex-base 用作几个非常不同的正则表达式引擎后端的接口。 Don Stewart 的 pcre-light 包没有这个抽象层,因此要小得多。

      Text.Regex.Posix 上的博客文章使用了我的 regex-posix 包,它也在 regex-base 之上。因此,regex-pcre 的用法与那篇博文非常相似,只是 PCRE 的编译和执行选项不同。

      对于配置 regex-pcre,Text.Regex.PCRE.Wrap module 具有您需要的常量。使用 regex-base 中的 makeRegexOptsM 指定选项。

      【讨论】:

        【解决方案4】:

        还有我写的regex-applicative

        这个想法是,您可以为正则表达式的每个部分分配一些含义,然后组合它们,就像您使用 Parsec 编写解析器一样。

        这是一个例子——简单的 URL 解析。

        import Text.Regex.Applicative
        
        data Protocol = HTTP | FTP deriving Show
        
        protocol :: RE Char Protocol
        protocol = HTTP <$ string "http" <|> FTP <$ string "ftp"
        
        type Host = String
        type Location = String
        data URL = URL Protocol Host Location deriving Show
        
        host :: RE Char Host
        host = many $ psym $ (/= '/')
        
        url :: RE Char URL
        url = URL <$> protocol <* string "://" <*> host <* sym '/' <*> many anySym
        
        main = print $ "http://stackoverflow.com/questions" =~ url
        

        【讨论】:

          【解决方案5】:

          我觉得rex 也很不错,我认为它的 ViewPatterns 集成是个好主意。

          虽然它可能很冗长,但这部分与正则表达式概念有关。

          parseDate :: String -> LocalTime
          parseDate [rex|(?{read -> year}\d+)-(?{read -> month}\d+)-
                  (?{read -> day}\d+)\s(?{read -> hour}\d+):(?{read -> mins}\d+):
                  (?{read -> sec}\d+)|] =
              LocalTime (fromGregorian year month day) (TimeOfDay hour mins sec)
          parseDate v@_ = error $ "invalid date " ++ v
          

          也就是说,我刚刚发现其他答案之一中提到的正则表达式应用程序,它可能是一个更好的选择,可能不那么冗长且更惯用,尽管如果您知道正则表达式,那么 rex 的学习曲线基本上为零加号。

          【讨论】:

            猜你喜欢
            • 2015-07-17
            • 2023-03-12
            • 2011-05-20
            • 2012-02-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多