-- RegexPR.hs -- -- Author: Yoshikuni Jujo -- module Text.RegexPR ( matchRegexPR , gmatchRegexPR -- EXPERIMENTAL , 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]