regex-do 1.6 → 1.7
raw patch · 8 files changed
+143/−97 lines, 8 files
Files
- regex-do.cabal +6/−2
- src/Text/Regex/Do/Pcre/Match.hs +36/−35
- src/Text/Regex/Do/Pcre/MatchSame.hs +37/−0
- src/Text/Regex/Do/Pcre/Matchf.hs +14/−7
- src/Text/Regex/Do/Pcre/Replace.hs +23/−23
- src/Text/Regex/Do/Pcre/Result.hs +5/−5
- src/Text/Regex/Do/TypeDo.hs +12/−12
- test/TestRegex/TestPcre.hs +10/−13
regex-do.cabal view
@@ -1,5 +1,5 @@ name: regex-do-version: 1.6+version: 1.7 synopsis: PCRE wrapper description: format, search, replace (String | ByteString) with PCRE regex. Utf8-safe author: Imants Cekusins@@ -10,7 +10,11 @@ cabal-version: >=1.10 build-type: Simple homepage: https://github.com/ciez/regex-do+source-repository head+ type: git+ location: https://github.com/ciez/regex-do.git + library exposed-modules: Text.Regex.Do.Trim@@ -23,7 +27,7 @@ Text.Regex.Do.TypeRegex Text.Regex.Do.Convert Text.Regex.Do.Pad-+ Text.Regex.Do.Pcre.MatchSame other-modules: Text.Regex.Do.Pcre.Matchf Text.Regex.Do.Pcre.Result
src/Text/Regex/Do/Pcre/Match.hs view
@@ -8,71 +8,72 @@ import Text.Regex.Do.TypeDo import Text.Regex.Do.Pcre.Option as O import Text.Regex.Do.TypeRegex-import qualified Text.Regex.Do.Pcre.Result as R-import Text.Regex.Do.Pcre.Matchf+import Text.Regex.Do.Pcre.Matchf as F+import Text.Regex.PCRE.Wrap() -{- | 'match' covers all+{- | 'match' covers all result types compiler looks up the appropriate function depending on the result type - ('=~') is borrowed from "Text.Regex.Posix.Wrap",- is a short version of 'match'. For those who put pattern & body in the right places.- -}-class Match n h out where- match::Pattern n -> Body h -> out- (=~)::n -> h -> out- (=~) n0 h0 = match (Pattern n0) (Body h0)+ '=~' is borrowed from "Text.Regex.PCRE.Wrap",+ is a short version of 'match' + See also "Text.Regex.Do.Pcre.MatchSame" -} +class Match a b out where+ match::Pattern a -> Body b -> out+ (=~)::a -> b -> out+ (=~) p0 b0 = match (Pattern p0) (Body b0)++ -- | match once-instance Rx_ n h => Match n h [h] where- match = matchOnce+instance Rx_ a b => Match a b [b] where+ match = once {- ^ >>> "^all" =~ "all the time"::[String] - \["all"\] -}-instance Rx_ n h => Match n h Bool where- match = matchTest+ \["all"\]++ "Text.Regex.Do.Pcre.MatchSame" -}+instance Rx_ a b => Match a b Bool where+ match p0 (Body b0) = R.matchTest (r_ p0) b0 {- ^ test >>> "в" =~ "тихо в лесу"::Bool True- -} + "Text.Regex.Do.Pcre.MatchSame" -}+ -- | match all-instance Rx_ n h => Match n h [[h]] where- match = matchAll+instance Rx_ a b => Match a b [[b]] where+ match = F.all {- ^ >>> "well" =~ "all is well that ends well"::[[ByteString]] - \[["well"\],\["well"\]] -}+ \[["well"\],\["well"\]] + "Text.Regex.Do.Pcre.MatchSame" -}+ -- | match once-instance Rx_ n h => Match n h [PosLen] where+instance Rx_ a b => Match a b [PosLen] where match p0 b0 = maybe [] id $ poslen_ p0 b0-{- ^ >>> ("и"::String) =~ ("бывает и хуже"::String)::[PosLen]-- \[(13,2)\] /Utf8/ -}---- | match all-instance Rx_ n h => Match n h [[PosLen]] where- match = poslen_+{- ^ >>> "и" =~ "бывает и хуже"::[PosLen] + \[(13,2)\] -matchOnce::Rx_ n h => Pattern n -> Body h -> [h] -- ^ matched content-matchOnce r0 b0 = maybe [] id $ R.allMatches b0 $ marray_ r0 b0+ /Utf8/ -matchTest::Rx_ n h => Pattern n -> Body h -> Bool-matchTest r0 (Body b0) = R.matchTest (r_ r0) b0+ "Text.Regex.Do.Pcre.MatchSame" -} -matchAll::Rx_ n h => Pattern n -> Body h -> [[h]] -- ^ matched content-matchAll r0 b0 = R.allMatches b0 $ marray_ r0 b0+-- | match all+instance Rx_ a b => Match a b [[PosLen]] where+ match = poslen_ -- | tweak Regex with options-makeRegexOpts::Opt_ n =>- [O.Comp] -> [O.Exec] -> Pattern n -> Regex+makeRegexOpts::Opt_ a =>+ [O.Comp] -> [O.Exec] -> Pattern a -> Regex makeRegexOpts comp0 exec0 (Pattern pat0) = rx1 where c1 = O.comp comp0 e1 = O.exec exec0
+ src/Text/Regex/Do/Pcre/MatchSame.hs view
@@ -0,0 +1,37 @@+module Text.Regex.Do.Pcre.MatchSame where++import Text.Regex.Do.TypeDo+import Text.Regex.PCRE.Wrap()+import Text.Regex.Do.Pcre.Match+import Data.ByteString+++{- | picks 'Match' instance where 'Pattern' and 'Body' are of the same type++ specify either 'Pattern' or 'Body' + 'out' types++ handy when working with 'OverloadedStrings'++ >>> ("^all"::String) -~ "all the time"::[String]++ \["all"\] -}+class MatchSame a out where+ match'::Match a a out => Pattern a -> Body a -> out+ match' = match+ (-~)::Match a a out => a -- ^ pattern+ -> a -- ^ body+ -> out -- ^ \- in ('-~') is the minus sign+ (-~) = (=~)+++instance MatchSame String Bool+instance MatchSame String [String]+instance MatchSame String [[String]]+instance MatchSame String [PosLen]+instance MatchSame String [[PosLen]]++instance MatchSame ByteString Bool+instance MatchSame ByteString [ByteString]+instance MatchSame ByteString [[ByteString]]+instance MatchSame ByteString [PosLen]+instance MatchSame ByteString [[PosLen]]
src/Text/Regex/Do/Pcre/Matchf.hs view
@@ -7,13 +7,20 @@ import qualified Text.Regex.Base.RegexLike as R hiding (makeRegex) -class (Rx_ n h, Functor f) => Matchf f n h where- marray_::Pattern n -> Body h -> f MatchArray- poslen_::Pattern n -> Body h -> f [PosLen]+class (Rx_ a b, Functor f) => Matchf f a b where+ marray_::Pattern a -> Body b -> f MatchArray+ poslen_::Pattern a -> Body b -> f [PosLen] poslen_ r0 b0 = R.poslen $ marray_ r0 b0 -instance Rx_ n h => Matchf Maybe n h where- marray_ r0 (Body b0) = R.matchOnce (r_ r0) b0+instance Rx_ a b => Matchf Maybe a b where+ marray_ p0 (Body b0) = R.matchOnce (r_ p0) b0 -instance Rx_ n h => Matchf [] n h where- marray_ r0 (Body b0) = R.matchAll (r_ r0) b0+instance Rx_ a b => Matchf [] a b where+ marray_ p0 (Body b0) = R.matchAll (r_ p0) b0+++once::Rx_ a b => Pattern a -> Body b -> [b] -- ^ matched content+once p0 b0 = maybe [] id $ R.allMatches b0 $ marray_ p0 b0++all::Rx_ a b => Pattern a -> Body b -> [[b]] -- ^ matched content+all p0 b0 = R.allMatches b0 $ marray_ p0 b0
src/Text/Regex/Do/Pcre/Replace.hs view
@@ -21,22 +21,25 @@ import Text.Regex.Do.Pcre.Matchf +type Mr_ a out = (Match a a out, Rx_ a a, Replace_ a, Opt_ a)++ class Mr_ a [a] => Replace a where replace::[ReplaceCase] -> Pattern a -> Replacement a -> Body a -> a- replace cases0 pat0 repl0 hay0 =+ replace cases0 p0 repl0 b0 = if isUtf8 cases0 then utfFn2- else fn2 (pat2 pat0,repl0) hay0+ else fn2 (pat2 p0,repl0) b0 where fn1 = if P.elem All cases0 then rall else ronce fn2 = if P.elem All cases0 then rall else ronce- utfFn2 = let res1 = fn1 (pat2 $ toByteString' <$> pat0, toByteString' <$> repl0) $ toByteString' <$> hay0+ utfFn2 = let res1 = fn1 (pat2 $ toByteString' <$> p0, toByteString' <$> repl0) $ toByteString' <$> b0 in toA res1- pat2 pat0 = addOpt pat0 cOpt1+ pat2 p0 = addOpt p0 cOpt1 cOpt1 = comp cases0 replaceGroup::[ReplaceCase] -> Pattern a -> GroupReplacer a -> Body a -> a- replaceGroup cases0 pat0 repl0 = fn1 pat2 repl0- where pat2 = addOpt pat0 cOpt+ replaceGroup cases0 p0 repl0 = fn1 pat2 repl0+ where pat2 = addOpt p0 cOpt cOpt = comp cases0 fn1 = if P.elem All cases0 then rallGroup@@ -89,10 +92,10 @@ instance Replace_ String where- prefix pl1 = P.take $ fst pl1- suffix pl1 = P.drop (pos1 + len1)- where pos1 = fst pl1- len1 = snd pl1+ prefix pl0 = P.take $ fst pl0+ suffix pl0 = P.drop (pos1 + len1)+ where pos1 = fst pl0+ len1 = snd pl0 concat' = P.concat toByteString' = toByteString toA = toString@@ -101,10 +104,10 @@ instance Replace_ B.ByteString where- prefix pl1 = B.take $ fst pl1- suffix pl1 = B.drop (pos1 + len1)- where pos1 = fst pl1- len1 = snd pl1+ prefix pl0 = B.take $ fst pl0+ suffix pl0 = B.drop (pos1 + len1)+ where pos1 = fst pl0+ len1 = snd pl0 concat' = B.concat toByteString' = id toA = id@@ -114,20 +117,20 @@ -- static ronce::Mr_ a [a] => (Pattern Regex, Replacement a) -> Body a -> a-ronce (pat1, Replacement repl1) h1@(Body h0) =- let pl2 = let m1 = marray_ pat1 h1+ronce (p0, Replacement repl0) h1@(Body h0) =+ let pl2 = let m1 = marray_ p0 h1 in R.poslen m1 in case pl2 of Nothing -> h0- Just lpl1 -> firstGroup lpl1 (repl1, h0)+ Just lpl1 -> firstGroup lpl1 (repl0, h0) rall::Mr_ a [a] => (Pattern Regex, Replacement a) -> Body a -> a-rall (pat1, Replacement repl1) h1@(Body h0) =- let lpl1 = let m1 = marray_ pat1 h1+rall (p0, Replacement repl0) h1@(Body h0) =+ let lpl1 = let m1 = marray_ p0 h1 in R.poslen m1::[[PosLen]]- foldFn1 lpl1 acc1 = firstGroup lpl1 (repl1,acc1)+ foldFn1 lpl1 acc1 = firstGroup lpl1 (repl0,acc1) in P.foldr foldFn1 h0 lpl1 @@ -226,6 +229,3 @@ isUtf8::[ReplaceCase] -> Bool isUtf8 case0 = Utf8 `P.elem` case0---type Mr_ a out = (Match a a out, Rx_ a a, Replace_ a, Opt_ a)
src/Text/Regex/Do/Pcre/Result.hs view
@@ -11,12 +11,12 @@ -- | all groups-allMatches::(Functor f, R.Extract a) =>- Body a -> f MatchArray -> f [a]+allMatches::(Functor f, R.Extract b) =>+ Body b -> f MatchArray -> f [b] allMatches hay0 results0 = groupMatch hay0 <$> results0 -- | matches for one group-groupMatch::R.Extract a =>- Body a -> MatchArray -> [a]-groupMatch (Body hay1) arr1 = [R.extract tuple1 hay1 | tuple1 <- A.elems arr1]+groupMatch::R.Extract b =>+ Body b -> MatchArray -> [b]+groupMatch (Body b0) a0 = [R.extract tuple1 b0 | tuple1 <- A.elems a0]
src/Text/Regex/Do/TypeDo.hs view
@@ -6,20 +6,20 @@ -- pcre-type GroupReplacer a = (MatchArray -> ReplaceAcc a -> ReplaceAcc a) -- MatchArray -> acc -> acc+type GroupReplacer b = (MatchArray -> ReplaceAcc b -> ReplaceAcc b) -- MatchArray -> acc -> acc -data ReplaceAcc a = ReplaceAcc {- acc::a, -- ^ Body with some replacements made+data ReplaceAcc b = ReplaceAcc {+ acc::b, -- ^ content with some replacements made pos_adj::Int {- ^ position adjustment: group replacement length may differ from replaced text length -} } -- | Needle-data Pattern n = Pattern n deriving (Functor) -- Bs, String, RegexPcre+data Pattern a = Pattern a deriving (Functor) -- Bs, String, RegexPcre -- | Haystack-data Body h = Body h deriving (Functor) -- Bs, String+data Body b = Body b deriving (Functor) -- Bs, String data Replacement r = Replacement r deriving (Functor) -- Bs, String @@ -34,18 +34,18 @@ -type Opt_ n = R.RegexMaker Regex CompOption ExecOption n-type Rx_ n h = (R.Extract h, Regex_ n, R.RegexLike Regex h)+type Opt_ a = R.RegexMaker Regex CompOption ExecOption a+type Rx_ a b = (Regex_ a, R.Extract b, R.RegexLike Regex b) -class Regex_ r where- r_::Pattern r -> Regex+class Regex_ a where+ r_::Pattern a -> Regex instance Regex_ ByteString where- r_ (Pattern r0) = R.makeRegex r0+ r_ (Pattern p0) = R.makeRegex p0 instance Regex_ String where- r_ (Pattern r0) = R.makeRegex r0+ r_ (Pattern p0) = R.makeRegex p0 instance Regex_ Regex where- r_ (Pattern r0) = r0+ r_ (Pattern p0) = p0
test/TestRegex/TestPcre.hs view
@@ -1,14 +1,11 @@-{-# LANGUAGE FlexibleContexts,- TypeFamilies #-} module TestRegex.TestPcre where import Test.Hspec import Text.Regex.Do.TypeDo as M import Text.Regex.Do.Pcre.Match as M-import Text.Regex.Do.Pcre.Matchf as M import Text.Regex.Do.Convert import Data.ByteString-+import Text.Regex.Do.Pcre.MatchSame as M main::IO() main = hspec $ describe " matchTest " $ do@@ -16,15 +13,15 @@ it " [String] " $ (M.match (Pattern n) h::[[String]]) `shouldBe` [["d1"],["d1"]] it " ?ByteString " $ (M.match (Pattern $ b n) (b <$> h)::[ByteString]) `shouldBe` [b "d1"] it " [ByteString] " $ (M.match (Pattern $ b n) (b <$> h)::[[ByteString]]) `shouldBe` [[b "d1"],[b "d1"]]- it " ша " $ M.match (Pattern ("^ша"::String)) (Body ("шапка"::String)) `shouldBe` True- it " cd " $ M.match (Pattern ("^cd"::String)) (Body ("abcde"::String)) `shouldBe` False- it " cd " $ M.poslen_ (Pattern ("^cd"::String)) (Body ("abcde"::String)) `shouldBe` []- it " ab " $ M.match (Pattern ("^ab"::String)) (Body ("abc"::String)) `shouldBe` True- it "doc 1" $ ("в"::ByteString) =~ ("тихо в лесу"::ByteString) `shouldBe` True- it "doc 2" $ ("^all"::String) =~ ("all the time"::String) `shouldBe` (["all"]::[String])- it "doc 3" $ ("^all"::ByteString) =~ ("all the time"::ByteString) `shouldBe` (["all"]::[ByteString])- it "doc 4" $ ("well"::ByteString) =~ ("all is well that ends well"::ByteString) `shouldBe` ([["well"],["well"]]::[[ByteString]])- it "doc 5" $ ("и"::String) =~ ("бывает и хуже"::String) `shouldBe` ([(13,2)]::[PosLen])+ it " ша " $ M.match' (Pattern ("^ша"::String)) (Body "шапка") `shouldBe` True+ it " cd " $ M.match' (Pattern ("^cd"::String)) (Body "abcde") `shouldBe` False+ it " cd " $ M.match' (Pattern ("^cd"::String)) (Body "abcde") `shouldBe` ([]::[PosLen])+ it " ab " $ M.match' (Pattern ("^ab"::String)) (Body "abc") `shouldBe` True+ it "doc 1" $ ("в"::ByteString) -~ "тихо в лесу" `shouldBe` True+ it "doc 2" $ ("^all"::String) -~ "all the time" `shouldBe` ["all"::String]+ it "doc 3" $ ("^all"::ByteString) -~ "all the time" `shouldBe` (["all"]::[ByteString])+ it "doc 4" $ ("well"::ByteString) -~ "all is well that ends well" `shouldBe` ([["well"],["well"]]::[[ByteString]])+ it "doc 5" $ ("и"::String) -~ "бывает и хуже" `shouldBe` ([(13,2)]::[PosLen]) n = "d1" h = Body "abcd1efg d1hij"