【问题标题】:Grouping in haskell regular expressions在haskell正则表达式中分组
【发布时间】:2011-04-08 15:04:23
【问题描述】:

如何在 Haskell 中使用正则表达式提取字符串?

let x = "xyz abc" =~ "(\\w+) \\w+" :: String

这没有匹配到

let x = "xyz abc" =~ "(.*) .*" :: String

确实如此,但 x 最终为“xyz abc”如何仅提取第一个正则表达式组以使 x 为“xyz”?

【问题讨论】:

    标签: regex haskell


    【解决方案1】:

    我编写/维护了 regex-baseregex-pcreregex-tdfa 等软件包。

    在 regex-base 中,Text.Regex.Base.Context 模块记录了 =~ 使用的大量 RegexContext 实例。这些是在 RegexLike 之上实现的,它提供了调用 matchText 和 matchAllText 的底层方法。

    KennyTM 提到的 [[String]] 是 RegexContext 的另一个实例,可能是也可能不是最适合您的实例。一个综合实例是

    RegexContext a b (AllTextMatches (Array Int) (MatchText b))
    
    type MatchText source = Array Int (source, (MatchOffset, MatchLength))
    

    可用于为所有内容获取MatchText

    let x :: Array Int (MatchText String)
        x = getAllTextMatches $ "xyz abc" =~ "(\\w+) \\w+"
    

    此时 x 是组匹配的 Array Int 匹配的 Array Int。

    请注意,“\w”是 Perl 语法,因此您需要 regex-pcre 才能访问它。如果你想要 Unix/Posix 扩展的正则表达式,你应该使用跨平台的 regex-tdfa,并避免使用 regex-posix,因为它会在实现 regex.h 库时遇到每个平台的错误。

    请注意,Perl 与 Posix 不只是像“\w”这样的语法问题。他们使用非常不同的算法并且经常返回不同的结果。此外,时间和空间复杂度也大不相同。为了匹配长度为 'n' 的字符串,Perl 样式 (regex-pcre) 的时间可以是 O(exp(n)),而使用 regex-posix 的 Posix 样式的时间总是 O(n)。

    【讨论】:

      【解决方案2】:

      将结果转换为[[String]]。然后你会得到一个匹配列表,每一个都是匹配的文本列表和捕获的子组。

      Prelude Text.Regex.PCRE> "xyz abc more text" =~ "(\\w+) \\w+" :: [[String]]
      [["xyz abc","xyz"],["more text","more"]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多