Haskell 和带交叉点的正则表达式

Haskell and Regex with Intersections

我正在使用 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)
[]

我期待返回一些值,但列表是空的。然而,这 returns 是预期的:

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

因此,如果我删除像 &&[^IO] 这样的交叉点,就没有问题。 正如我刚刚发现的那样,PCRE 不支持交叉路口。 Haskell 有任何支持它的替代库吗?

PCRE 不支持字符 class intersection/subtraction.

但是,您可以使用否定前瞻和其他方法解决它。

此处,将"(\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]

另一种更冗长的方法是拼出字符 classes:

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

所以,不匹配IO[C-X]必须写成[C-HJ-NP-X]