{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
module Text.Regex (
Regex,
mkRegex,
mkRegexWithOpts,
matchRegex,
matchRegexAll,
subRegex,
splitRegex
) where
import Data.Array((!))
import Data.Bits((.|.))
import Text.Regex.Base(RegexMaker(makeRegexOpts),defaultExecOpt,RegexLike(matchAll,matchAllText),RegexContext(matchM),MatchText)
import Text.Regex.Posix(Regex,compNewline,compIgnoreCase,compExtended)
mkRegex :: String -> Regex
mkRegex :: String -> Regex
mkRegex s :: String
s = CompOption -> ExecOption -> String -> Regex
forall regex compOpt execOpt source.
RegexMaker regex compOpt execOpt source =>
compOpt -> execOpt -> source -> regex
makeRegexOpts CompOption
opt ExecOption
forall regex compOpt execOpt.
RegexOptions regex compOpt execOpt =>
execOpt
defaultExecOpt String
s
where opt :: CompOption
opt = CompOption
compExtended CompOption -> CompOption -> CompOption
forall a. Bits a => a -> a -> a
.|. CompOption
compNewline
mkRegexWithOpts
:: String
-> Bool
-> Bool
-> Regex
mkRegexWithOpts :: String -> Bool -> Bool -> Regex
mkRegexWithOpts s :: String
s single_line :: Bool
single_line case_sensitive :: Bool
case_sensitive
= let opt :: CompOption
opt = (if Bool
single_line then (CompOption
compNewline CompOption -> CompOption -> CompOption
forall a. Bits a => a -> a -> a
.|.) else CompOption -> CompOption
forall a. a -> a
id) (CompOption -> CompOption)
-> (CompOption -> CompOption) -> CompOption -> CompOption
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(if Bool
case_sensitive then CompOption -> CompOption
forall a. a -> a
id else (CompOption
compIgnoreCase CompOption -> CompOption -> CompOption
forall a. Bits a => a -> a -> a
.|.)) (CompOption -> CompOption) -> CompOption -> CompOption
forall a b. (a -> b) -> a -> b
$
CompOption
compExtended
in CompOption -> ExecOption -> String -> Regex
forall regex compOpt execOpt source.
RegexMaker regex compOpt execOpt source =>
compOpt -> execOpt -> source -> regex
makeRegexOpts CompOption
opt ExecOption
forall regex compOpt execOpt.
RegexOptions regex compOpt execOpt =>
execOpt
defaultExecOpt String
s
matchRegex
:: Regex
-> String
-> Maybe [String]
matchRegex :: Regex -> String -> Maybe [String]
matchRegex p :: Regex
p str :: String
str = ((String, String, String, [String]) -> [String])
-> Maybe (String, String, String, [String]) -> Maybe [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(_,_,_,str :: [String]
str) -> [String]
str) (Regex -> String -> Maybe (String, String, String, [String])
matchRegexAll Regex
p String
str)
matchRegexAll
:: Regex
-> String
-> Maybe ( String, String, String, [String] )
matchRegexAll :: Regex -> String -> Maybe (String, String, String, [String])
matchRegexAll p :: Regex
p str :: String
str = Regex -> String -> Maybe (String, String, String, [String])
forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
matchM Regex
p String
str
subRegex :: Regex
-> String
-> String
-> String
subRegex :: Regex -> String -> String -> String
subRegex _ "" _ = ""
subRegex regexp :: Regex
regexp inp :: String
inp repl :: String
repl =
let compile :: Int
-> String
-> [(String, (Int, Int))]
-> Array i (String, b)
-> String
-> String
compile _i :: Int
_i str :: String
str [] = \ _m :: Array i (String, b)
_m -> (String
strString -> String -> String
forall a. [a] -> [a] -> [a]
++)
compile i :: Int
i str :: String
str (("\\",(off :: Int
off,len :: Int
len)):rest :: [(String, (Int, Int))]
rest) =
let i' :: Int
i' = Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
len
pre :: String
pre = Int -> String -> String
forall a. Int -> [a] -> [a]
take (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i) String
str
str' :: String
str' = Int -> String -> String
forall a. Int -> [a] -> [a]
drop (Int
i'Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i) String
str
in if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
str' then \ _m :: Array i (String, b)
_m -> (String
pre String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ('\\'Char -> String -> String
forall a. a -> [a] -> [a]
:)
else \ m :: Array i (String, b)
m -> (String
pre String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ('\\' Char -> String -> String
forall a. a -> [a] -> [a]
:) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int
-> String
-> [(String, (Int, Int))]
-> Array i (String, b)
-> String
-> String
compile Int
i' String
str' [(String, (Int, Int))]
rest Array i (String, b)
m
compile i :: Int
i str :: String
str ((xstr :: String
xstr,(off :: Int
off,len :: Int
len)):rest :: [(String, (Int, Int))]
rest) =
let i' :: Int
i' = Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
len
pre :: String
pre = Int -> String -> String
forall a. Int -> [a] -> [a]
take (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i) String
str
str' :: String
str' = Int -> String -> String
forall a. Int -> [a] -> [a]
drop (Int
i'Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i) String
str
x :: i
x = String -> i
forall a. Read a => String -> a
read String
xstr
in if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
str' then \ m :: Array i (String, b)
m -> (String
preString -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((String, b) -> String
forall a b. (a, b) -> a
fst (Array i (String, b)
mArray i (String, b) -> i -> (String, b)
forall i e. Ix i => Array i e -> i -> e
!i
x))String -> String -> String
forall a. [a] -> [a] -> [a]
++)
else \ m :: Array i (String, b)
m -> (String
preString -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((String, b) -> String
forall a b. (a, b) -> a
fst (Array i (String, b)
mArray i (String, b) -> i -> (String, b)
forall i e. Ix i => Array i e -> i -> e
!i
x))String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int
-> String
-> [(String, (Int, Int))]
-> Array i (String, b)
-> String
-> String
compile Int
i' String
str' [(String, (Int, Int))]
rest Array i (String, b)
m
compiled :: MatchText String -> String -> String
compiled :: MatchText String -> String -> String
compiled = Int
-> String
-> [(String, (Int, Int))]
-> MatchText String
-> String
-> String
forall i b.
(Ix i, Read i) =>
Int
-> String
-> [(String, (Int, Int))]
-> Array i (String, b)
-> String
-> String
compile 0 String
repl [(String, (Int, Int))]
findrefs where
bre :: Regex
bre = String -> Regex
mkRegex "\\\\(\\\\|[0-9]+)"
findrefs :: [(String, (Int, Int))]
findrefs = (MatchText String -> (String, (Int, Int)))
-> [MatchText String] -> [(String, (Int, Int))]
forall a b. (a -> b) -> [a] -> [b]
map (\m :: MatchText String
m -> ((String, (Int, Int)) -> String
forall a b. (a, b) -> a
fst (MatchText String
mMatchText String -> Int -> (String, (Int, Int))
forall i e. Ix i => Array i e -> i -> e
!1),(String, (Int, Int)) -> (Int, Int)
forall a b. (a, b) -> b
snd (MatchText String
mMatchText String -> Int -> (String, (Int, Int))
forall i e. Ix i => Array i e -> i -> e
!0))) (Regex -> String -> [MatchText String]
forall regex source.
RegexLike regex source =>
regex -> source -> [MatchText source]
matchAllText Regex
bre String
repl)
go :: Int -> String -> [MatchText String] -> String
go _i :: Int
_i str :: String
str [] = String
str
go i :: Int
i str :: String
str (m :: MatchText String
m:ms :: [MatchText String]
ms) =
let (_,(off :: Int
off,len :: Int
len)) = MatchText String
mMatchText String -> Int -> (String, (Int, Int))
forall i e. Ix i => Array i e -> i -> e
!0
i' :: Int
i' = Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
len
pre :: String
pre = Int -> String -> String
forall a. Int -> [a] -> [a]
take (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i) String
str
str' :: String
str' = Int -> String -> String
forall a. Int -> [a] -> [a]
drop (Int
i'Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i) String
str
in if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
str' then String
pre String -> String -> String
forall a. [a] -> [a] -> [a]
++ (MatchText String -> String -> String
compiled MatchText String
m "")
else String
pre String -> String -> String
forall a. [a] -> [a] -> [a]
++ (MatchText String -> String -> String
compiled MatchText String
m (Int -> String -> [MatchText String] -> String
go Int
i' String
str' [MatchText String]
ms))
in Int -> String -> [MatchText String] -> String
go 0 String
inp (Regex -> String -> [MatchText String]
forall regex source.
RegexLike regex source =>
regex -> source -> [MatchText source]
matchAllText Regex
regexp String
inp)
splitRegex :: Regex -> String -> [String]
splitRegex :: Regex -> String -> [String]
splitRegex _ [] = []
splitRegex delim :: Regex
delim strIn :: String
strIn =
let matches :: [(Int, Int)]
matches = (Array Int (Int, Int) -> (Int, Int))
-> [Array Int (Int, Int)] -> [(Int, Int)]
forall a b. (a -> b) -> [a] -> [b]
map (Array Int (Int, Int) -> Int -> (Int, Int)
forall i e. Ix i => Array i e -> i -> e
!0) (Regex -> String -> [Array Int (Int, Int)]
forall regex source.
RegexLike regex source =>
regex -> source -> [Array Int (Int, Int)]
matchAll Regex
delim String
strIn)
go :: Int -> String -> [(Int, Int)] -> [String]
go _i :: Int
_i str :: String
str [] = String
str String -> [String] -> [String]
forall a. a -> [a] -> [a]
: []
go i :: Int
i str :: String
str ((off :: Int
off,len :: Int
len):rest :: [(Int, Int)]
rest) =
let i' :: Int
i' = Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
len
firstline :: String
firstline = Int -> String -> String
forall a. Int -> [a] -> [a]
take (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i) String
str
remainder :: String
remainder = Int -> String -> String
forall a. Int -> [a] -> [a]
drop (Int
i'Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i) String
str
in Int -> [String] -> [String]
forall a b. a -> b -> b
seq Int
i' ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$
if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
remainder then [String
firstline,""]
else String
firstline String -> [String] -> [String]
forall a. a -> [a] -> [a]
: Int -> String -> [(Int, Int)] -> [String]
go Int
i' String
remainder [(Int, Int)]
rest
in Int -> String -> [(Int, Int)] -> [String]
go 0 String
strIn [(Int, Int)]
matches