module Text.Regex.DFA.String(
Regex
,MatchOffset
,MatchLength
,CompOption
,ExecOption
,compile
,execute
,regexec
) where
import Data.Array(listArray,Array,elems,(!))
import Text.Regex.DFA.ReadRegex(parseRegex)
import Text.Regex.Base.RegexLike(RegexMaker(..),RegexLike(..),RegexContext(..),MatchOffset,MatchLength)
import Text.Regex.DFA.Wrap(Regex(..),CompOption,ExecOption,makeCompat)
import Text.Regex.DFA.Engine(findRegex,matchesRegex,countRegex,accept)
import Text.Regex.DFA.Transitions(noLoop)
import Text.Regex.Base.Impl(polymatch,polymatchM)
instance RegexContext Regex String String where
match = polymatch
matchM = polymatchM
unwrap :: Either String v -> v
unwrap x = case x of Left err -> error ("Text.Regex.Parsec.String died: "++ err)
Right v -> v
compile :: CompOption
-> ExecOption
-> String
-> Either String Regex
compile compOpt execOpt source =
case parseRegex source of
Left err -> Left ("parseRegex for DFA failed:"++show err)
Right (patternRead,_) ->
let pattern = noLoop patternRead
lexer = accept (makeCompat compOpt pattern)
in Right (Regex pattern lexer compOpt execOpt)
execute :: Regex
-> String
-> Either String (Maybe (Array Int (MatchOffset,MatchLength)))
execute r s = Right (matchOnce r s)
regexec :: Regex
-> String
-> Either String (Maybe (String, String, String, [String]))
regexec r s =
case matchOnceText r s of
Nothing -> Right (Nothing)
Just (pre,mt,post) ->
let main = fst (mt!0)
rest = map fst (tail (elems mt))
in Right (Just (pre,main,post,rest))
instance RegexMaker Regex CompOption ExecOption String where
makeRegexOpts c e source = unwrap (compile c e source)
makeRegexOptsM c e source = either fail return (compile c e source)
instance RegexLike Regex String where
matchOnce r source =
case findRegex regex source of
(_,_,Nothing) -> Nothing
(_,lenBefore, Just (_,lenOf,_)) -> Just $
listArray (0,0) [(lenBefore,lenOf)]
where regex = asLexer r
matchAll r source = loop 0 source
where loop n s | n `seq` False = undefined
| otherwise =
case findRegex regex s of
(_,_,Nothing) -> []
(_,lenBefore, Just (_,0,_)) ->
listArray (0,0) [(n+lenBefore,0)] : []
(_,lenBefore, Just (_,lenOf,s')) ->
listArray (0,0) [(n+lenBefore,lenOf)] : loop (n+lenBefore+lenOf) s'
regex = asLexer r
matchTest r source = matchesRegex regex source
where regex = asLexer r
matchCount r source = countRegex regex source
where regex = asLexer r