在haskell正则表达式中分组

时间:2011-04-08 06:16:42

标签: regex haskell

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

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

这不是事件得到匹配

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

但是x会以“xyz abc”结尾,如何只提取第一个正则表达式组,使x为“xyz”?

2 个答案:

答案 0 :(得分:18)

我编写/维护了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 vs Posix不仅仅是“\ w”这样的语法问题。他们使用非常不同的算法,并经常返回不同的结果此外,时间和空间的复杂性也非常不同。对于长度为'n'的字符串匹配,Perl样式(regex-pcre)的时间可以是O(exp(n)),而使用regex-posix的Posix样式在时间上总是O(n)。

答案 1 :(得分:14)

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

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