在Haskell中的两个子串之间提取字符串

时间:2017-08-02 17:45:53

标签: regex haskell substring

我想在这个SO问题Find string between two substrings中修改python正则表达式(PCRE)技术到Haskell,以便我可以在Haskell中做同样的事情。

但我无法弄清楚如何让它在GHC(8.2.1)中发挥作用。我已安装cabal install regex-pcre,并在搜索后提出以下测试代码:

import Text.Regex.PCRE
s = "+++asdf=5;iwantthis123jasd---"
result = (s ++ s) =~ "asdf=5;(.*)123jasd" :: [[String]]

我希望得到中间字符串的第一个和最后一个实例

iwantthis

但我无法得到正确的结果:

  

[[" ASDF = 5; iwantthis123jasd --- +++ ASDF = 5; iwantthis123jasd"" iwantthis123jasd --- +++ ASDF = 5; iwantthis"]]

我之前没有在Haskell中使用正则表达式或pcre。

有人可以帮助正确使用(提取第一次和最后一次)吗? 另外,我不太了解::[[String]]这里的:: [[String]]用法。它做了什么以及为什么有必要?

我搜索了documentation,但未发现类型转换为CLBeaconRegion的用法。

1 个答案:

答案 0 :(得分:4)

您获得的结果如下:

Prelude Text.Regex.PCRE> (s ++ s) =~ "asdf=5;(.*)123jasd" :: [[String]]
[["asdf=5;iwantthis123jasd---+++asdf=5;iwantthis123jasd","iwantthis123jasd---+++asdf=5;iwantthis"]]

这是正确的,第一个元素是隐式捕获组0(整个正则表达式),第二个元素是捕获组1的元素(匹配(.*)。因为匹配如下:

+++asdf=5;iwantthis123jasd---+++asdf=5;iwantthis123jasd---

所以它仍然匹配asdf=5;123jasd部分。

这是因为Kleene开始*匹配贪心:它旨在尽可能地捕获。您可以使用(.*?)来使用非贪婪的量词:

Prelude Text.Regex.PCRE> (s ++ s) =~ "asdf=5;(.*?)123jasd" :: [[String]]
[["asdf=5;iwantthis123jasd","iwantthis"],["asdf=5;iwantthis123jasd","iwantthis"]]

现在我们获得两个匹配。每个匹配都有"iwantthis"作为捕获组1。

您可以在其上使用map (head . tail)map (!!1)来获取(.*?)部分的捕获列表:

Prelude Text.Regex.PCRE> map (!!1) ((s ++ s) =~ "asdf=5;(.*?)123jasd" :: [[String]])
["iwantthis","iwantthis"]