在haskell正则表达式中分组

sip*_*wiz 16 regex haskell

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

let x = "xyz abc" =~ "(\\w+) \\w+" :: String
Run Code Online (Sandbox Code Playgroud)

这不是事件得到匹配

let x = "xyz abc" =~ "(.*) .*" :: String
Run Code Online (Sandbox Code Playgroud)

这样做,但x最终为"xyz abc",我如何只提取第一个正则表达式组,使x为"xyz"?

Chr*_*icz 18

我编写/维护了像regex-base,regex-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))
Run Code Online (Sandbox Code Playgroud)

可用于获取所有内容的MatchText:

let x :: Array Int (MatchText String)
    x = getAllTextMatches $ "xyz abc" =~ "(\\w+) \\w+"
Run Code Online (Sandbox Code Playgroud)

此时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).


ken*_*ytm 14

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

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