packages feed

regex-do 1.6 → 1.7

raw patch · 8 files changed

+143/−97 lines, 8 files

Files

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"