module Text.RegexPR (
matchRegexPR
, gmatchRegexPR
, subRegexPR
, gsubRegexPR
, splitRegexPR
) where
import Hidden.RegexPRCore ( matchRegexPRVerbose )
import Hidden.RegexPRTypes( RegexResult, MatchList )
import Data.Char ( isDigit )
matchRegexPR :: String -> String -> Maybe ( RegexResult, MatchList )
matchRegexPR reg str
= fmap ( \( (pre, ret, (_, rest)), ml ) -> ( (ret, (pre, rest)), ml ) ) $
matchRegexPRVerbose reg ("", str)
gmatchRegexPR :: String -> String -> [ ( RegexResult, MatchList ) ]
gmatchRegexPR reg str = gmatchRegexPRGen Nothing reg ("", str)
gmatchRegexPRGen ::
Maybe (String, String) -> String -> (String, String) -> [ ( RegexResult, MatchList ) ]
gmatchRegexPRGen pmp reg str
= case matchRegexPRVerbose reg str of
Just ((pre, ret, sp@(p,rest@(~(x:xs)))), ml)
-> case (pmp, sp) of
(Just (_, ""), _) -> [ ( (ret, (pre, rest)), ml ) ]
_ | Just sp == pmp -> ( (ret, (pre, rest)), ml ) :
gmatchRegexPRGen pmp reg (x:p, xs)
| otherwise -> ( (ret, (pre, rest)), ml ) :
gmatchRegexPRGen (Just sp) reg sp
Nothing -> []
subRegexPR :: String -> String -> String -> String
subRegexPR reg sub src
= case matchRegexPRVerbose reg ("",src) of
Just al@((pre, _, sp), _) -> pre ++ subBackRef al sub ++ snd sp
Nothing -> src
gsubRegexPR :: String -> String -> String -> String
gsubRegexPR reg sub src = gsubRegexPRGen Nothing reg sub ("", src)
gsubRegexPRGen ::
Maybe (String, String) -> String -> String -> (String, String) -> String
gsubRegexPRGen pmp reg sub src
= case matchRegexPRVerbose reg src of
Just al@((pre, _, sp@(~(p,x:xs))), _)
-> case (pmp, sp) of
(Just (_, ""), _) -> ""
_ | Just sp == pmp -> pre ++ [x] ++
gsubRegexPRGen (Just sp) reg sub (x:p, xs)
| otherwise -> pre ++ subBackRef al sub ++
gsubRegexPRGen (Just sp) reg sub sp
Nothing -> snd src
subBackRef ::
((String, String, (String, String)), MatchList) -> String -> String
subBackRef (_, _) "" = ""
subBackRef al@((_, match, (hasRead,post)), ml) ('\\':str@(c:rest))
| elem c "&0" = match ++ subBackRef al rest
| c == '`' = reverse (drop (length match) hasRead) ++ subBackRef al rest
| c == '\'' = post ++ subBackRef al rest
| c == '+' = snd (head ml) ++ subBackRef al rest
| c == '{' = maybe "" id (lookup (read $ takeWhile (/='}') rest) ml) ++
subBackRef al (tail $ dropWhile (/='}') str)
| otherwise = maybe "" id (lookup (read $ takeWhile isDigit str) ml) ++
subBackRef al (dropWhile isDigit str)
subBackRef al (c:cs) = c : subBackRef al cs
splitRegexPR :: String -> String -> [String]
splitRegexPR reg str
= let gmatched = gmatchRegexPR reg str
in map (fst.snd.fst) gmatched ++ [(snd.snd.fst.last) gmatched]