Haskell和正则表达式与交叉点

时间:2017-02-28 20:12:15

标签: regex haskell pcre

我正在使用带有Haskell的正则表达式和Text.Regex.PCRE,在我的情况下我有:

Prelude Text.Regex.PCRE> getAllTextMatches ("32UMU1078" =~ "(\\d{1,2})([C-X&&[^IO]])([A-Z&&[^IO]])([A-Z&&[^IO]])(\\d{2,10})" :: AllTextMatches [] String)
[]

我期待返回一些值,但列表为空。然而,这会返回预期的结果:

Prelude Text.Regex.PCRE> getAllTextMatches ("32UMU1078" =~ "(\\d{1,2})([C-X])([A-Z])([A-Z])(\\d{2,10})" :: AllTextMatches [] String)
["32UMU1078"]

因此,如果删除&&[^IO]之类的交叉点,则没有问题。 正如我刚刚发现PCRE不支持交叉路口。任何支持Haskell的替代库?

1 个答案:

答案 0 :(得分:2)

PCRE不支持字符类交集/减法。

但是,您可以使用负面前瞻和其他方法解决这个问题。

在此处,将"(\\d{1,2})([C-X&&[^IO]])([A-Z&&[^IO]])([A-Z&&[^IO]])(\\d{2,10})"替换为

"(\\d{1,2})((?![IO])[C-X])((?![IO])[A-Z])((?![IO])[A-Z])(\\d{2,10})"
            ^^^^^^^^^^^^^  ^^^^^^^^^^^^^  ^^^^^^^^^^^^^

也就是说,用前瞻替换减法,[C-X&&[^IO]] - > (?![IO])[C-X]

另一种更详细的方法是拼出字符类:

"(\\d{1,2})([C-HJ-NP-X])([A-HJ-NP-Z])([A-HJ-NP-Z])(\\d{2,10})"

因此,与[C-X]I不匹配的O必须写为[C-HJ-NP-X]