【问题标题】:extract string between two substrings in Haskell在Haskell中的两个子字符串之间提取字符串
【发布时间】:2017-08-02 17:45:52
【问题描述】:

我想将这个 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 中使用过 regex 或 pcre。

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

我搜索了documentation,但没有发现将类型转换为:: [[String]] 的用法。

【问题讨论】:

    标签: regex haskell substring


    【解决方案1】:

    你得到的结果如下:

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

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

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

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

    这是因为 Kleene start * 匹配 greedy:它旨在尽可能多地捕获。您可以使用 (.*?) 但是使用 non-greedy 量词:

    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"]

    【讨论】:

    • map (!! 1) 可能更具可读性,因为数字表示捕获组。
    猜你喜欢
    • 2013-01-31
    • 2013-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    相关资源
    最近更新 更多