{-# LANGUAGE FlexibleContexts #-}
module ShellCheck.Regex where
import Data.List
import Data.Maybe
import Control.Monad
import Text.Regex.TDFA
mkRegex :: String -> Regex
mkRegex :: String -> Regex
mkRegex String
str =
let make :: String -> Regex
make :: String -> Regex
make = String -> Regex
forall regex compOpt execOpt source.
RegexMaker regex compOpt execOpt source =>
source -> regex
makeRegex
in
String -> Regex
make String
str
matches :: String -> Regex -> Bool
matches :: String -> Regex -> Bool
matches = (Regex -> String -> Bool) -> String -> Regex -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Regex -> String -> Bool
forall regex source target.
RegexContext regex source target =>
regex -> source -> target
match
matchRegex :: Regex -> String -> Maybe [String]
matchRegex :: Regex -> String -> Maybe [String]
matchRegex Regex
re String
str = do
(_, _, _, groups) <- Regex -> String -> Maybe (String, String, String, [String])
forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
forall (m :: * -> *).
MonadFail m =>
Regex -> String -> m (String, String, String, [String])
matchM Regex
re String
str :: Maybe (String,String,String,[String])
return groups
matchAllStrings :: Regex -> String -> [String]
matchAllStrings :: Regex -> String -> [String]
matchAllStrings Regex
re = (String -> Maybe (String, String)) -> String -> [String]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr String -> Maybe (String, String)
f
where
f :: String -> Maybe (String, String)
f :: String -> Maybe (String, String)
f String
str = do
(_, match, rest, _) <- Regex -> String -> Maybe (String, String, String, [String])
forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
forall (m :: * -> *).
MonadFail m =>
Regex -> String -> m (String, String, String, [String])
matchM Regex
re String
str :: Maybe (String, String, String, [String])
return (match, rest)
matchAllSubgroups :: Regex -> String -> [[String]]
matchAllSubgroups :: Regex -> String -> [[String]]
matchAllSubgroups Regex
re = (String -> Maybe ([String], String)) -> String -> [[String]]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr String -> Maybe ([String], String)
f
where
f :: String -> Maybe ([String], String)
f :: String -> Maybe ([String], String)
f String
str = do
(_, _, rest, groups) <- Regex -> String -> Maybe (String, String, String, [String])
forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
forall (m :: * -> *).
MonadFail m =>
Regex -> String -> m (String, String, String, [String])
matchM Regex
re String
str :: Maybe (String, String, String, [String])
return (groups, rest)
subRegex :: Regex -> String -> String -> String
subRegex :: Regex -> String -> String -> String
subRegex Regex
re String
input String
replacement = String -> String
f String
input
where
f :: String -> String
f String
str = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
str (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ do
(before, match, after) <- Regex -> String -> Maybe (String, String, String)
forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
forall (m :: * -> *).
MonadFail m =>
Regex -> String -> m (String, String, String)
matchM Regex
re String
str :: Maybe (String, String, String)
when (null match) $ error ("Internal error: substituted empty in " ++ str)
return $ before ++ replacement ++ f after
splitOn :: String -> Regex -> [String]
splitOn :: String -> Regex -> [String]
splitOn String
input Regex
re =
case Regex -> String -> Maybe (String, String, String)
forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
forall (m :: * -> *).
MonadFail m =>
Regex -> String -> m (String, String, String)
matchM Regex
re String
input :: Maybe (String, String, String) of
Just (String
before, String
match, String
after) -> String
before String -> [String] -> [String]
forall a. a -> [a] -> [a]
: String
after String -> Regex -> [String]
`splitOn` Regex
re
Maybe (String, String, String)
Nothing -> [String
input]