module Text.Regex.Easy
( module Text.Regex.PCRE
, Match, Source
, (=~+)
, (=~-)
, (=~#)
, (=~++)
, replaceRegex
, replaceRegexAll
)
where
import Data.Array as AR
import Data.Function
import Data.List as List
import Data.Monoid
import Data.String.Conversions
import Prelude hiding ((++))
import Text.Regex.PCRE
import qualified Data.ByteString.Lazy as LBS
tests :: Bool
tests = and $
(("file_1.txt" =~+ "^(.*)_(\\d).txt$") ==
[ ( "file_1.txt" , ( 0 , 10 ) )
, ( "file" , ( 0 , 4 ) )
, ( "1" , ( 5 , 1 ) )
]) :
(("file_1.txt" =~- "^(.*)_(\\d).txt$") ==
["file_1.txt", "file", "1"]) :
("file_1.txt" =~# "^(.*)_(\\d).txt$") :
(let q :: LBS = "wif kwof ..wif,, wif, 8fwif"
p :: SBS = "\\Sw.f"
in ((q =~+ p) ==
[ ( "kwof" , ( 4 , 4 ) ) ]) &&
((q =~++ p) ==
[ [ ( "kwof" , ( 4 , 4 ) ) ]
, [ ( ".wif" , ( 10 , 4 ) ) ]
, [ ( "fwif" , ( 24 , 4 ) ) ]
])) :
(let q :: LBS = "wif kwof ..wif,, wif, 8fwif"
p :: SBS = "\\Sw.f"
f ([(a,_)] :: [(LBS, (MatchOffset, MatchLength))]) = Just $ "@" <> a <> "@"
in (replaceRegex q p f == "wif @kwof@ ..wif,, wif, 8fwif") &&
(replaceRegexAll q p f == "wif @kwof@ .@.wif@,, wif, 8@fwif@")) :
[]
type Match = SBS
type Source = LBS
(=~+) :: Source -> Match -> [(Source, (MatchOffset, MatchLength))]
(=~+) source match = elems (getAllTextSubmatches (source =~ match) :: MatchText Source)
(=~-) :: Source -> Match -> [Source]
(=~-) source match = map fst $ source =~+ match
(=~#) :: Source -> Match -> Bool
(=~#) source match = not . null $ source =~+ match
(=~++) :: Source -> Match -> [[(Source, (MatchOffset, MatchLength))]]
(=~++) source match = case source =~+ match of
[] -> []
x@((_, (holeStart, holeEnd)):_) -> x : map (shift (holeStart + holeEnd))
(LBS.drop (fromIntegral $ holeStart + holeEnd) source =~++ match)
where
shift :: Int -> [(Source, (MatchOffset, MatchLength))] -> [(Source, (MatchOffset, MatchLength))]
shift o' = map (\ (s, (o, l)) -> (s, (o + o', l)))
replaceRegex :: Source -> Match -> ([(Source, (MatchOffset, MatchLength))] -> Maybe Source) -> Source
replaceRegex source match trans = case source =~+ match of
m@((_, (offset, length)):_) -> let before = LBS.take (fromIntegral offset) source
after = LBS.drop (fromIntegral $ offset + length) source
in case trans m of
Just m' -> before <> m' <> after
Nothing -> source
replaceRegexAll :: Source -> Match -> ([(Source, (MatchOffset, MatchLength))] -> Maybe Source) -> Source
replaceRegexAll source match trans = case source =~+ match of
[] -> source
m@((_, (offset, length)):_) -> case trans m of
Just m' -> let before = LBS.take (fromIntegral offset) source
after = LBS.drop (fromIntegral $ offset + length) source
in before <> m' <> replaceRegexAll after match trans
Nothing -> let before = LBS.take (fromIntegral $ offset + length) source
after = LBS.drop (fromIntegral $ offset + length) source
in before <> replaceRegexAll after match trans