Ключ к использованию matchAll
использует аннотацию типа :: Regex
при создании regexs:
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,1),(3,1),(4,1),(7,1),(8,1),(9,1),(10,1),(11,1),(13,1),(14,1),(15,1),(16,1),(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),(1,1),(3,1),(4,1),(7,1),(8,1),(9,1),(10,1),(11,1),(13,1),(14,1),(15,1),(16,1),(18,1)]
смотрите документацию для Text.Regex.Base.Context для получения более подробной информации о том, что контексты доступны.
UPDATE: Я считаю, что конструктор типа AllMatches
был введен для разрешения неоднозначности введен, когда регулярное выражение имеет подвыражения - например:
foo = "axx ayy" =~ "a(.)([^a])"
test1 = getAllMatches $ (foo :: AllMatches [] (MatchOffset, MatchLength))
-- [(0,3),(3,3)]
-- returns the locations of "axx" and "ayy" but no subexpression info
test2 = foo :: MatchArray
-- array (0,2) [(0,(0,3)),(1,(1,1)),(2,(2,1))]
-- returns only the match with "axx"
Оба, по существу, список пар смещения длины, но они означают разные вещи.
"typecast :: Regex" не относится к типу. Существует не изменение времени выполнения типа данных. Это аннотация типа – Squidly
да - это лучший способ описать ее. – ErikR