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