{-# 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 = 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 = forall a b c. (a -> b -> c) -> b -> a -> c
flip 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
(String
_, String
_, String
_, [String]
groups) <- forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
matchM Regex
re String
str :: Maybe (String,String,String,[String])
forall (m :: * -> *) a. Monad m => a -> m a
return [String]
groups
matchAllStrings :: Regex -> String -> [String]
matchAllStrings :: Regex -> String -> [String]
matchAllStrings Regex
re = 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
(String
_, String
match, String
rest, [String]
_) <- forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
matchM Regex
re String
str :: Maybe (String, String, String, [String])
forall (m :: * -> *) a. Monad m => a -> m a
return (String
match, String
rest)
matchAllSubgroups :: Regex -> String -> [[String]]
matchAllSubgroups :: Regex -> String -> [[String]]
matchAllSubgroups Regex
re = 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
(String
_, String
_, String
rest, [String]
groups) <- forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
matchM Regex
re String
str :: Maybe (String, String, String, [String])
forall (m :: * -> *) a. Monad m => a -> m a
return ([String]
groups, String
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 = forall a. a -> Maybe a -> a
fromMaybe String
str forall a b. (a -> b) -> a -> b
$ do
(String
before, String
match, String
after) <- forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
matchM Regex
re String
str :: Maybe (String, String, String)
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
match) forall a b. (a -> b) -> a -> b
$ forall a. HasCallStack => String -> a
error (String
"Internal error: substituted empty in " forall a. [a] -> [a] -> [a]
++ String
str)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String
before forall a. [a] -> [a] -> [a]
++ String
replacement forall a. [a] -> [a] -> [a]
++ String -> String
f String
after
splitOn :: String -> Regex -> [String]
splitOn :: String -> Regex -> [String]
splitOn String
input Regex
re =
case forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
matchM Regex
re String
input :: Maybe (String, String, String) of
Just (String
before, String
match, String
after) -> String
before forall a. a -> [a] -> [a]
: String
after String -> Regex -> [String]
`splitOn` Regex
re
Maybe (String, String, String)
Nothing -> [String
input]