我试图匹配正则表达式的所有出现并得到索引作为结果.来自Real World
Haskell的例子说我能做到
string =~ regex :: [(Int,Int)]
但是,由于自RWH发布以来正在更新正则表达式库,因此这已被破坏. (见All matches of regex in Haskell和“=~” raise “No instance for (RegexContext Regex [Char] [String])”).这样做的正确方法是什么?
更新:
我发现matchAll可能会给我我想要的东西.但我不知道如何使用它.
使用matchAll的关键是在创建正则表达式时使用类型注释:: Regex:
import Text.Regex import Text.Regex.Base re = makeRegex "[^aeIoU]" :: Regex test = matchAll re "the quick brown fox"
这将返回一个数组列表.要获取(偏移,长度)对的列表,只需访问每个数组的第一个元素:
import Data.Array ((!)) matches = map (!0) $matchAll re "the quick brown fox" -- [(0,1),(1,(3,(4,(7,(8,(9,(10,(11,(13,(14,(15,(16,(18,1)]
要使用=〜运算符,事情可能会因RWH而发生变化.您应该使用预定义类型MatchOffset和MatchLength以及特殊类型构造函数AllMatches:
import Text.Regex.Posix re = "[^aeIoU]" text = "the quick brown fox" test1 = text =~ re :: Bool -- True test2 = text =~ re :: String -- "t" test3 = text =~ re :: (MatchOffset,MatchLength) -- (0,1) test4 = text =~ re :: AllMatches [] (MatchOffset,MatchLength) -- (not showable) test4' = getAllMatches $(text =~ re :: AllMatches [] (MatchOffset,MatchLength)) -- [(0,1)]
有关可用的上下文的更多详细信息,请参阅Text.Regex.Base.Context的文档.
更新:我相信引入了类型构造函数AllMatches来解决当正则表达式具有子表达式时引入的歧义 – 例如:
foo = "axx ayy" =~ "a(.)([^a])" test1 = getAllMatches $(foo :: AllMatches [] (MatchOffset,3),3)] -- returns the locations of "axx" and "ayy" but no subexpression info test2 = foo :: MatchArray -- array (0,2) [(0,(0,3)),1)),(2,1))] -- returns only the match with "axx"
两者基本上都是偏移长度对的列表,但它们意味着不同的东西.