packages feed

regex-do 2.5 → 2.6

raw patch · 12 files changed

+261/−44 lines, 12 files

Files

changelog.md view
@@ -1,7 +1,15 @@+#####   2.6+  compatible with 2.5   +  +  overload replace (both Ascii & Utf8): add shorter arg versions  + #####   2.5   *API changes*+   split PCRE to Ascii and Utf8+   remove \[Comp\] opt from replace signature   +   tweak trim    #####   2.4
regex-do.cabal view
@@ -1,5 +1,5 @@ name:                regex-do-version:             2.5+version:             2.6 synopsis:            PCRE wrapper description:         format, search, replace (String | ByteString) with PCRE regex. Utf8-safe author:              Imants Cekusins
src/Text/Regex/Do/Pcre/Ascii/Match.hs view
@@ -7,6 +7,7 @@  module Text.Regex.Do.Pcre.Ascii.Match     (Match(..),+    (=~),     R.extract   -- | 'extract' is reexport from "Text.Regex.Base.RegexLike"     ) where @@ -25,14 +26,19 @@     '=~' is borrowed from "Text.Regex.PCRE.Wrap",     is a short version of 'match' +    precompiled Regex may be used as pattern too. see "Text.Regex.Do.Pcre.Utf8.Match"+     See also "Text.Regex.Do.Pcre.Ascii.MatchHint"       -}  class Match a b out where     match::Pattern a -> Body b -> out-    (=~)::a     -- ^ pattern-        -> b    -- ^ body-        -> out-    (=~) p0 b0 = match (Pattern p0) (Body b0)+++(=~)::Match a b out =>+    a     -- ^ pattern+    -> b    -- ^ body+    -> out+(=~) p0 b0 = match (Pattern p0) (Body b0)   -- | match once
src/Text/Regex/Do/Pcre/Ascii/MatchHint.hs view
@@ -35,10 +35,11 @@     match::hint (Pattern a) -> Body a -> F hint a     match h0 = M.match $ unhint h0 -    (=~)::hint a  -- ^ hint & pattern-            -> a          -- ^ body-            -> F hint a   -- ^ type defined by the instance, determined by the hint-    (=~) h0 = (M.=~) $ unhint h0+(=~)::MatchHint hint a =>+        hint a  -- ^ hint & pattern+        -> a          -- ^ body+        -> F hint a   -- ^ type defined by the instance, determined by the hint+(=~) h0 = (M.=~) $ unhint h0   instance MatchHint Test String where
src/Text/Regex/Do/Pcre/Ascii/Replace.hs view
@@ -1,10 +1,9 @@-{- | === Ascii vs Utf8 modules--    for reliable results with Utf8 pattern or body,+{- | for reliable results with Utf8 pattern or body,     use "Text.Regex.Do.Pcre.Utf8.Replace"   -}  module Text.Regex.Do.Pcre.Ascii.Replace     (Replace(..),+    Replace'(),     Repl_)  where  import Text.Regex.Base.RegexLike as R@@ -18,11 +17,59 @@ import Text.Regex.Do.Type.MatchHint import Text.Regex.Do.Pcre.Option as O +{- | arg overloading    -}+class Replace pat repl body out where+    replace::pat -> repl -> body -> out -class Replace all a repl b where-    replace::(R_ b, Matchf all b) =>-        all (Pattern a) -> repl b -> Body b -> b +instance (T.Regex a, Hint all, Replace' all a repl b) =>+    Replace (all (Pattern a)) (repl b) (Body b) b where+    replace = replace'+{- ^ full typed arg++    >>> replace (Once (Pattern "^a\\s")) (Replacement "A") (Body "a bc")    -}+++instance (T.Regex a, Hint all, Replace' all a repl b, Functor all) =>+    Replace (all a) (repl b) b b where+    replace p0 r0 b0 = replace' (Pattern <$> p0) r0 $ Body b0+{- ^ hint 'Pattern'++    >>> replace (Once "^a\\s") (Replacement "A") "a bc"     -}+++instance (T.Regex a, Hint all, Replace' all a repl b) =>+    Replace a (all(repl b)) b b where+    replace p0 r0 b0 = replace' p1 (unhint r0) $ Body b0+        where p1 = swap r0 $ Pattern p0+{- ^ hint repl++    >>> replace "^a\\s" (Once (Replacement "A")) "a bc"   -}+++instance (T.Regex a, Replace' Once a repl b) =>+    Replace a (repl b) (Once b) b where+    replace p0 r0 b0 = replace' p1 r0 $ Body $ unhint b0+        where p1 = swap b0 $ Pattern p0+{- ^ hint 'Body'++    >>> replace "^a\\s" (Replacement "A") $ Once "a bc"   -}+++instance (T.Regex a, Replace' All a repl b) =>+    Replace a (repl b) (All b) b where+    replace p0 r0 b0 = replace' p1 r0 $ Body $ unhint b0+        where p1 = swap b0 $ Pattern p0+-- ^ hint 'Body'+++{- | internal class & instances++    use 'replace' instead  -}+class Replace' all a repl b where+    replace'::all (Pattern a) -> repl b -> Body b -> b++ type Repl_ f rx r a = (T.Regex rx,                         R.RegexLike R.Regex a,                         Extract' a,@@ -35,8 +82,8 @@   -instance Repl_ Maybe a repl b => Replace Once a repl b where-    replace = replace_ marray_+instance Repl_ Maybe a repl b => Replace' Once a repl b where+    replace' = replace_ marray_  {- ^ === static replace for simple (no group) needle @@ -53,8 +100,8 @@      "a=[1 0 1] b=3 12"     -}  -instance Repl_ [] a repl b => Replace All a repl b where-    replace = replace_ marray_+instance Repl_ [] a repl b => Replace' All a repl b where+    replace' = replace_ marray_   {- ^ to tweak regex with 'O.Comp' or 'O.Exec', see "Text.Regex.Do.Type.Regex"
src/Text/Regex/Do/Pcre/Utf8/Match.hs view
@@ -35,14 +35,18 @@ (=~) p0 b0 = match (Pattern $ Utf8_ p0) (Body $ Utf8_ b0)  --- | match once-instance Rx_ a b => Match Utf8_ a b [b] where-    match p0 b0 = once (mr_ p0) $ val <$> b0+{- | match once -{- ^ >>> let rx1 = makeRegexOpt' (Pattern $ toByteString' "左") [] []      --  add options as needed+    ==== precompiled regex as pattern++ >>> let rx1 = makeRegexOpt' (Pattern $ toByteString' "左") [] []      --  add options as needed          rx2 = Utf8_ <$> rx1          m1 = U.match rx2 (Body $ toByteString' "100メートル左折後、左")::[ByteString]       m1 `shouldBe` [toByteString "左"]        -}++instance Rx_ a b => Match Utf8_ a b [b] where+    match p0 b0 = once (mr_ p0) $ val <$> b0+   instance Rx_ a b => Match Utf8_ a b Bool where
src/Text/Regex/Do/Pcre/Utf8/Replace.hs view
@@ -6,7 +6,8 @@     __'toByteString''__ converts String to 'Utf8_' 'ByteString'     -}  module Text.Regex.Do.Pcre.Utf8.Replace-    (Replace(..))  where+    (Replace(..),+    Replace'())  where  import Prelude as P import Text.Regex.Do.Type.Do@@ -17,17 +18,106 @@ import Text.Regex.Do.Convert import Data.ByteString +{- | arg overloading    -}+class Replace pat repl body out where+    replace::pat -> repl -> body -> out -class Replace all enc a repl where-    replace::all (Pattern (enc a)) -> repl (enc a) -> Body (enc a) -> a +instance (Replace' all enc b repl) =>+    Replace (all (Pattern (enc b))) (repl (enc b)) (Body (enc b)) b where+    replace = replace'+{- ^ full typed arg -instance Replace Once Utf8_ String Replacement where-    replace = replace_str marray_+    >>> replace (Once $ Pattern $ Utf8_ "праздник")+            (Replacement $ Utf8_ "радость")+            (Body $ Utf8_ "экзамен - всегда праздник")+-} -instance Replace All Utf8_ String Replacement where-    replace = replace_str marray_ +instance (T.Regex b, Hint all,+        Replace' all Utf8_ b repl,+        Functor all,+        Enc' repl Utf8_) =>+    Replace (all b) (repl b) b b where+    replace p0 r0 b0 = replace' p1 (enc' r0) $+            Body $ Utf8_ b0+            where p1 = Pattern  . Utf8_ <$> p0+{- ^ hint 'Pattern'++    >>> replace (All "праздник")+            (Replacement "радость")+            "экзамен - всегда праздник"+    -}+++instance (T.Regex b, Hint all,+        Replace' all Utf8_ b repl,+        Functor all,+        Enc' repl Utf8_) =>+    Replace b (all (repl b)) b b where+    replace p0 r0 b0 = replace' p1 (enc' $ unhint r0) $+            Body $ Utf8_ b0+        where p1 = swap r0 $ Pattern $ Utf8_ p0+{- ^ hint repl++    >>> replacer::GroupReplacer (ByteString)+    replacer = defaultReplacer 1 tweak1+          where tweak1 s1+                    | s1 == toByteString "[команды]" = toByteString "A - B"+                    | s1 == toByteString "[счёт]" = toByteString "5:0"+                    | s1 == toByteString "[какая боль, ]" = empty+                    | otherwise = traceShow s1 $ toByteString "?"++    >>> let rx1 = toByteString "(\\[[^\\]]+\\])"+            body1 = toByteString "[какая боль, ][команды] : [счёт]"+        in replace rx1 (All replacer) body1++    "A - B : 5:0"       -}++instance (T.Regex b,+        Replace' Once Utf8_ b repl,+        Enc' repl Utf8_) =>+    Replace b (repl b) (Once b) b where+    replace p0 r0 b0 = replace' p1 (enc' r0) $+            Body $ Utf8_ $ unhint b0+        where p1 = swap b0 $ Pattern $ Utf8_ p0+{- ^ hint 'Body'++    >>> replace "праздник"+            (Replacement "радость")+            (Once "экзамен - всегда праздник")+    -}+++instance (T.Regex b,+        Replace' All Utf8_ b repl,+        Enc' repl Utf8_) =>+    Replace b (repl b) (All b) b where+    replace p0 r0 b0 = replace' p1 (enc' r0) $+            Body $ Utf8_ $ unhint b0+        where p1 = swap b0 $ Pattern $ Utf8_ p0+{- ^ hint 'Body'++    >>> replace "праздник"+            (Replacement "радость")+            (All "экзамен - всегда праздник")+    -}++++{- | internal class & instances++    use 'replace' instead  -}+class Replace' all enc a repl where+    replace'::all (Pattern (enc a)) -> repl (enc a) -> Body (enc a) -> a+++instance Replace' Once Utf8_ String Replacement where+    replace' = replace_str marray_++instance Replace' All Utf8_ String Replacement where+    replace' = replace_str marray_+ replace_str f0 p0 r0 b0 =    let ma1 = f0 p1 b1        b1 = toByteString . val <$> b0@@ -36,11 +126,11 @@    in toString $ O.replace ma1 r1 b1  -instance Replace Once Utf8_ ByteString Replacement where-    replace = replace_bs marray_+instance Replace' Once Utf8_ ByteString Replacement where+    replace' = replace_bs marray_ -instance Replace All Utf8_ ByteString Replacement where-    replace = replace_bs marray_+instance Replace' All Utf8_ ByteString Replacement where+    replace' = replace_bs marray_  replace_bs f0 p0 r0 b0 =    let ma1 = f0 p1 b1@@ -50,11 +140,11 @@   -instance Replace Once Utf8_ ByteString GroupReplacer where-    replace = replace_bs' marray_+instance Replace' Once Utf8_ ByteString GroupReplacer where+    replace' = replace_bs' marray_ -instance Replace All Utf8_ ByteString GroupReplacer where-    replace = replace_bs' marray_+instance Replace' All Utf8_ ByteString GroupReplacer where+    replace' = replace_bs' marray_  {- ^ >>> replacer::GroupReplacer (Utf8_ ByteString)          replacer = defaultReplacer 1 tweak1
src/Text/Regex/Do/Trim.hs view
@@ -17,11 +17,11 @@   instance Trim B.ByteString where-    trim bs1 = replace (All rx2) repl1 $ Body bs1+    trim bs1 = replace rx2 repl1 (All bs1)        where repl1 = Replacement B.empty              rx1 = "(^[\\s\\t]+)|([\\s\\t]+$)"              rx2 = let p1 = Pattern $ toByteString rx1-                        in makeRegexOpt' p1 [Blank] []+                        in makeRegexOpt p1 [Blank] []   instance  Trim String where
src/Text/Regex/Do/Type/Do.hs view
@@ -69,3 +69,7 @@         \ma1 acc1 -> val <$> (fn0 ma1 $ enc <$> acc1)     enc' (GroupReplacer fn0) = GroupReplacer $         \ma1 acc1 -> enc <$> (fn0 ma1 $ val <$> acc1)++instance Enc enc => Enc' Replacement enc where+    val' = (val <$>)+    enc' = (enc <$>)
src/Text/Regex/Do/Type/MatchHint.hs view
@@ -45,3 +45,7 @@ instance Applicative All where     pure p0 = All p0     (<*>) (All f0) (All a0) = All $ f0 a0+++swap::Hint hint => hint a -> b -> hint b+swap _ = hint
test/TestRegex/TestReplace.hs view
@@ -25,10 +25,10 @@ doc = hspec $ do        describe "Pcre.Replace doc" $ do           it "replaceGroup 1" $ do-            replace (Once (Pattern "\\w=(\\d{1,3})")) replacer (Body "a=101 b=3 12")+            replace (Once "\\w=(\\d{1,3})") replacer "a=101 b=3 12"                 `shouldBe` "a=[сто один] b=3 12"           it "replaceGroup 2" $ do-            replace (All (Pattern "\\w=(\\d{1,3})")) replacer (Body "a=101 b=3 12")+            replace (All "\\w=(\\d{1,3})") replacer "a=101 b=3 12"                 `shouldBe` "a=[сто один] b=[three] 12"           it "replace 3" $ do             U.replace (Once (Pattern $ Utf8_ "менее")) (Replacement $ Utf8_ $ "более") (Body $ Utf8_ "менее менее")@@ -37,7 +37,7 @@             U.replace (All (Pattern $ Utf8_ "менее")) (Replacement $ Utf8_ $ "боле") (Body $ Utf8_ "менее менее")                 `shouldBe` "боле боле"           it "replace 5" $ do-            replace (Once (Pattern "^a\\s")) (Replacement "A") (Body "a bc хол.гор.")+            replace (Once "^a\\s") (Replacement "A") "a bc хол.гор."                 `shouldBe` "Abc хол.гор."  
test/TestRegex/TestReplaceUtf.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE NoOverloadedStrings #-} module TestRegex.TestReplaceUtf where  import Test.Hspec@@ -7,11 +8,41 @@ import Text.Regex.Do.Pcre.Utf8.Replace as U import Text.Regex.Do.Type.MatchHint import Text.Regex.Do.ReplaceOpen+import Debug.Trace   main::IO()-main = groupReplace+main = do+     groupReplace+     groupReplace2_+     doc ++doc::IO()+doc = hspec $ do+       describe "TestRegex.TestReplaceUtf doc" $ do+            it "doc 1" $+                U.replace (All "праздник") (Replacement "радость") "экзамен - всегда праздник"+                        `shouldBe` out1+            it "doc 2" $+                U.replace "праздник" (All (Replacement "радость")) "экзамен - всегда праздник"+                        `shouldBe` out1+            it "doc 3" $+                U.replace "праздник" (Replacement "радость") (All "экзамен - всегда праздник")+                        `shouldBe` out1+            it "doc 4" $+                U.replace "праздник" (Replacement "радость") (Once "экзамен - всегда праздник")+                        `shouldBe` out1+            it "doc 2-bs" $+                U.replace (toByteString "праздник") (All (Replacement $ toByteString "радость")) (toByteString "экзамен - всегда праздник")+                        `shouldBe` (toByteString out1)+            it "doc 4-2" $+                U.replace (Once $ Pattern $ Utf8_ "праздник") (Replacement $ Utf8_ "радость") (Body $ Utf8_ "экзамен - всегда праздник")+                        `shouldBe` out1+        where out1 = "экзамен - всегда радость"+++ groupReplace::IO() groupReplace =  hspec $ do        describe "TestRegex.TestReplaceUtf" $ do@@ -29,3 +60,25 @@                             if bs1 == toByteString' "左" then                                   "ー右ー"                                   else "?"+++groupReplace2_::IO()+groupReplace2_ =  hspec $ do+       describe "TestRegex.TestReplaceUtf" $ do+            it "боль" $ do+               runFn1 `shouldBe` (toByteString "A - B : 5:0")+            where runFn1 =+                     let rx1 = toByteString "(\\[[^\\]]+\\])"+                         body1 = toByteString "[какая боль, ][команды] : [счёт]"+                     in U.replace rx1 (All replacer2_) body1+++replacer2_::GroupReplacer (ByteString)+replacer2_ = defaultReplacer 1 tweak1+      where tweak1 s1+                | s1 == toByteString "[команды]" = toByteString "A - B"+                | s1 == toByteString "[счёт]" = toByteString "5:0"+                | s1 == toByteString "[какая боль, ]" = empty+                | otherwise = traceShow s1 $ toByteString "?"++