regex-examples 0.14.0.0 → 1.0.0.0
raw patch · 39 files changed
+1762/−1008 lines, 39 filesdep ~regexdep ~regex-with-pcre
Dependency ranges changed: regex, regex-with-pcre
Files
- README.markdown +2/−2
- changelog +13/−1
- data/include-result.lhs +5/−12
- data/pcre-macros.txt +2/−2
- data/pcre-nginx-log-processor.txt +2/−2
- data/pp-result-doc.lhs +6/−13
- data/pp-result-gen.lhs +5/−9
- data/pp-test.lhs +4/−9
- data/tdfa-macros.txt +2/−2
- examples/TestKit.lhs +30/−3
- examples/re-include.lhs +0/−2
- examples/re-nginx-log-processor.lhs +8/−5
- examples/re-prep.lhs +43/−24
- examples/re-sort-imports.lhs +2/−1
- examples/re-tests.lhs +8/−7
- examples/re-tutorial-options.lhs +221/−6
- examples/re-tutorial-replacing.lhs +211/−6
- examples/re-tutorial-testbench.lhs +154/−6
- examples/re-tutorial-tools.lhs +204/−6
- examples/re-tutorial.lhs +154/−667
- lib/cabal-masters/executables-incl.cabal +1/−1
- lib/cabal-masters/library-incl.cabal +4/−2
- lib/cabal-masters/mega-regex.cabal +2/−0
- lib/cabal-masters/regex.cabal +3/−0
- lib/cabal-masters/test-extra-source-files-incl.cabal +1/−0
- lib/mega-regex.cabal +33/−28
- lib/version.txt +1/−1
- regex-examples.cabal +34/−31
- src/Text/RE/PCRE/ByteString.hs +60/−16
- src/Text/RE/PCRE/ByteString/Lazy.hs +60/−16
- src/Text/RE/PCRE/Sequence.hs +60/−16
- src/Text/RE/PCRE/String.hs +60/−16
- src/Text/RE/TDFA/ByteString.hs +60/−16
- src/Text/RE/TDFA/ByteString/Lazy.hs +60/−16
- src/Text/RE/TDFA/Sequence.hs +60/−16
- src/Text/RE/TDFA/String.hs +60/−16
- src/Text/RE/TDFA/Text.hs +60/−16
- src/Text/RE/TDFA/Text/Lazy.hs +60/−16
- stack-8.0.yaml +7/−0
README.markdown view
@@ -12,7 +12,7 @@ * regular expression macros including: + a number of useful RE macros; + a test bench for testing and documenting new macro environments;- * built-in support for the TDFA and PCRE backends;+ * built-in support for the TDFA and PCRE back ends; * comprehensive documentation, tutorials and copious examples. @@ -78,7 +78,7 @@ ☒ 2017-04-04 v0.14.0.0 [Move IsOption, rename Find functions](https://github.com/iconnect/regex/milestone/18) - ☐ 2017-04-10 v1.0.0.0 [First stable release](https://github.com/iconnect/regex/milestone/3)+ ☒ 2017-04-10 v1.0.0.0 [First stable release](https://github.com/iconnect/regex/milestone/3) ☐ 2017-08-31 v2.0.0.0 [Fast text replacement with benchmarks](https://github.com/iconnect/regex/milestone/4)
changelog view
@@ -1,5 +1,17 @@ -*-change-log-*- +1.0.0.0 Chris Dornan <chris.dornan@irisconnect.co.uk> 2017-04-10+ * Rewrite tutorials (#113)+ * Add Text.RE.Tools.IsRegex (#122)+ * Include Macro Parsers in Core API (#123)+ * Adjust type of lookupCaptureID and friends (#124)+ * re-prep to handle cast example expressions (#125)+ * Rename compileSearchReplaceWithOptions (#126)+ * Hide ZeInternals, Evacuate Text.RE (#127)+ * Proper Haddocks for the quasi quoters (#128)+ * ed_ quasi quoters are being restricted to SimpleREOptions (#129)+ * regex dependeny on pcre-builtin (#130)+ 0.14.0.0 Chris Dornan <chris.dornan@irisconnect.co.uk> 2017-04-05 * Move IsOption into the back ends (#115) * Rename Find functions (#116)@@ -71,7 +83,7 @@ * Fix .travis.yml release-stack script (#67) 0.6.0.0 Chris Dornan <chris.dornan@irisconnect.co.uk> 2017-03-13- * Split out rexex-with-pcre package (#65)+ * Split out regex-with-pcre package (#65) 0.5.0.0 Chris Dornan <chris.dornan@irisconnect.co.uk> 2017-03-05 * Fix inter-operation of =~ & =~~ and named captures (#55)
data/include-result.lhs view
@@ -25,32 +25,25 @@ \begin{code} import Control.Applicative-import TestKit \end{code} An (self-)include directive <div class='includedcodeblock'> \begin{code}-evalme_PPT_01 = checkThis "" (Just 0) $- length <$>- Just []+evalme_PPT_01 = checkThis "" (Just 0) $ (length <$> Just []) \end{code} </div> --A one-line evalme fragment.+evalme frgment 1 \begin{code}-evalme_PPT_00 = checkThis "" 0 $- length []+evalme_PPT_00 = checkThis "" (0) $ length [] \end{code} -An evalme fragment spread over a couple of lines.+evalme frgment 1 \begin{code}-evalme_PPT_01 = checkThis "" (Just 0) $- length <$>- Just []+evalme_PPT_01 = checkThis "" (Just 0) $ (length <$> Just []) \end{code} And the main bottom stuff.
data/pcre-macros.txt view
@@ -37,7 +37,7 @@ |%email.simple |0 |[a-zA-Z0-9%_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0\|user-name%foo.bar.com@an-example.com | | |- |an email address | | |\-9.-]+ | |not-an-email-address | | | | | | | |@not-an-email-address | | | -|%frac |0 |-?[0-9]+(?:\.[0-9]+)? |0 | | |parseInteger |a decimal integer +|%frac |0 |-?[0-9]+(?:\.[0-9]+)? |0 | | |parseInteger |a decimal natural number | | | |1234567890 |0A | | | | | | |00 |+0 | | | | | | |01 |0. | | | @@ -99,7 +99,7 @@ | | | | |January | | | | | | | |01 | | | | | | | |1 | | | -|%string.simple |0 |"[^"[:cntrl:]]*" |"" | | |parseSimpleString|a decimal integer +|%string.simple |0 |"[^"[:cntrl:]]*" |"" | | |parseSimpleString|a simple quoted string | | | |"foo" |" | | | | | | |"\" |"\"" | | | | | | |"" |"\"\"" | | |
data/pcre-nginx-log-processor.txt view
@@ -37,7 +37,7 @@ |%email.simple |0 |[a-zA-Z0-9%_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0\|user-name%foo.bar.com@an-example.com | | |- |an email address | | |\-9.-]+ | |not-an-email-address | | | | | | | |@not-an-email-address | | | -|%frac |0 |-?[0-9]+(?:\.[0-9]+)? |0 | | |parseInteger |a decimal integer +|%frac |0 |-?[0-9]+(?:\.[0-9]+)? |0 | | |parseInteger |a decimal natural number | | | |1234567890 |0A | | | | | | |00 |+0 | | | | | | |01 |0. | | | @@ -99,7 +99,7 @@ | | | | |January | | | | | | | |01 | | | | | | | |1 | | | -|%string.simple |0 |"[^"[:cntrl:]]*" |"" | | |parseSimpleString|a decimal integer +|%string.simple |0 |"[^"[:cntrl:]]*" |"" | | |parseSimpleString|a simple quoted string | | | |"foo" |" | | | | | | |"\" |"\"" | | | | | | |"" |"\"\"" | | |
data/pp-result-doc.lhs view
@@ -11,7 +11,6 @@ \end{code} \begin{code}-{-# OPTIONS_GHC -fno-warn-missing-signatures #-} \end{code} And here is an empty one.@@ -24,33 +23,27 @@ \begin{code} import Control.Applicative-import TestKit \end{code} An (self-)include directive <div class='includedcodeblock'> \begin{code}-evalme_PPT_01 = checkThis "" (Just 0) $- length <$>- Just []+evalme_PPT_01 = checkThis "" (Just 0) $ (length <$> Just []) \end{code} </div> --A one-line evalme fragment.+evalme frgment 1 \begin{code}-evalme_PPT_00 = checkThis "" 0 $- length []+ghci> length []+0 \end{code} -An evalme fragment spread over a couple of lines.+evalme frgment 1 \begin{code}-ghci> +ghci> length <$> Just [] Just 0- length <$>- Just [] \end{code} And the main bottom stuff.
data/pp-result-gen.lhs view
@@ -34,25 +34,20 @@ \begin{code} import Control.Applicative-import TestKit \end{code} An (self-)include directive %include "data/pp-test.lhs" "^evalme_PPT_01" --A one-line evalme fragment.+evalme frgment 1 \begin{code}-evalme_PPT_00 = checkThis "" 0 $- length []+evalme_PPT_00 = checkThis "evalme_PPT_00" (0) $ length [] \end{code} -An evalme fragment spread over a couple of lines.+evalme frgment 1 \begin{code}-evalme_PPT_01 = checkThis "evalme_PPT_01" (Just 0) $- length <$>- Just []+evalme_PPT_01 = checkThis "evalme_PPT_01" (Just 0) $ (length <$> Just []) \end{code} And the main bottom stuff.@@ -60,6 +55,7 @@ main :: IO () main = runTheTests [ evalme_PPT_01+ , evalme_PPT_00 ] \end{code}
data/pp-test.lhs view
@@ -25,25 +25,20 @@ \begin{code} import Control.Applicative-import TestKit \end{code} An (self-)include directive %include "data/pp-test.lhs" "^evalme_PPT_01" --A one-line evalme fragment.+evalme frgment 1 \begin{code}-evalme_PPT_00 = checkThis "" 0 $- length []+evalme_PPT_00 = checkThis "" (0) $ length [] \end{code} -An evalme fragment spread over a couple of lines.+evalme frgment 1 \begin{code}-evalme_PPT_01 = checkThis "" (Just 0) $- length <$>- Just []+evalme_PPT_01 = checkThis "" (Just 0) $ (length <$> Just []) \end{code} And the main bottom stuff.
data/tdfa-macros.txt view
@@ -37,7 +37,7 @@ |%email.simple |0 |[a-zA-Z0-9%_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0\|user-name%foo.bar.com@an-example.com | | |- |an email address | | |\-9.-]+ | |not-an-email-address | | | | | | | |@not-an-email-address | | | -|%frac |1 |-?[0-9]+(\.[0-9]+)? |0 | | |parseInteger |a decimal integer +|%frac |1 |-?[0-9]+(\.[0-9]+)? |0 | | |parseInteger |a decimal natural number | | | |1234567890 |0A | | | | | | |00 |+0 | | | | | | |01 |0. | | | @@ -106,7 +106,7 @@ | | | |"\"\\\"" | | | | | | | |"\"foo\"" | | | | | | | |"" | | | | -|%string.simple |0 |"[^"[:cntrl:]]*" |"" | | |parseSimpleString|a decimal integer +|%string.simple |0 |"[^"[:cntrl:]]*" |"" | | |parseSimpleString|a simple quoted string | | | |"foo" |" | | | | | | |"\" |"\"" | | | | | | |"" |"\"\"" | | |
examples/TestKit.lhs view
@@ -17,9 +17,13 @@ , substVersion , substVersion_ , readCurrentVersion- , Test+ , Test(..) , runTheTests , checkThis+ , checkThisWith+ , convertMaybeTextList+ , castInt+ , packLBS , test_pp , include , cmp@@ -140,14 +144,28 @@ exitWith $ ExitFailure 1 checkThis :: (Show a,Eq a) => String -> a -> a -> Test-checkThis lab ref val =+checkThis = checkThisWith id++checkThisWith :: (Show a,Eq a) => (b->a) -> String -> b -> a -> Test+checkThisWith f lab ref0 val = Test { testLabel = lab , testExpected = show ref , testResult = show val , testPassed = ref == val }+ where+ ref = f ref0 +convertMaybeTextList :: [Maybe String] -> [Maybe T.Text]+convertMaybeTextList = map $ fmap T.pack++castInt :: Int -> Int+castInt = id++packLBS :: String -> LBS.ByteString+packLBS = LBS.pack+ present_test :: Test -> String present_test Test{..} = unlines [ "test: " ++ testLabel@@ -181,6 +199,12 @@ ------------------------ \begin{code}+-- | this function looks for lines of the form+--+-- `%include <file> [exclude <RE>]`+--+-- and replaces them with the contents of the named file, optionally+-- excluding any lines that match the given RE. include :: LBS.ByteString -> IO LBS.ByteString include = sed' $ Select [ Function [re|^%include ${file}(@{%string})$|] TOP incl@@ -191,6 +215,9 @@ incl _ mtch _ _ = include' mtch nop _ _ _ _ = return Nothing +-- | processes the match from a '%include' line, analyses the match,+-- fetches the file, optionally excludes lines specified by an RE,+-- returning the text to include. include' :: Match LBS.ByteString -> IO (Maybe LBS.ByteString) include' mtch = do ftr <- case prs_s <$> mtch !$$? [cp|rex|] of@@ -263,7 +290,7 @@ (hdr,bdy) = span (not . anyMatches . getLineMatches) lns lns = grepFilter rex lbs- rex = [re|^import +(qualified)? +${mod}([^ ].*)$|]+ rex = [re|^import +(qualified| ) ${mod}([^ ].*)$|] \end{code}
examples/re-include.lhs view
@@ -31,10 +31,8 @@ import Prelude.Compat import System.Environment import TestKit-import Text.RE import Text.RE.Replace import Text.RE.TDFA.ByteString.Lazy-import Text.RE.TestBench import Text.RE.Tools.Edit import Text.RE.Tools.Grep import Text.RE.Tools.Sed
examples/re-nginx-log-processor.lhs view
@@ -43,7 +43,7 @@ import System.IO import TestKit import Text.Printf-import Text.RE+import qualified Text.RE.PCRE as PCRE import Text.RE.PCRE.ByteString.Lazy import qualified Text.RE.PCRE.String as S import Text.RE.REOptions@@ -274,13 +274,13 @@ -- REOptions and Prelude -- -lpo :: REOptions-lpo = makeREOptions lp_prelude+lpo :: PCRE.REOptions+lpo = PCRE.makeREOptions lp_prelude lp_prelude :: Macros RE lp_prelude = runIdentity $ mkMacros mk regexType ExclCaptures lp_env where- mk = maybe oops Identity . compileRegexWithOptions noPreludeREOptions+ mk = maybe oops Identity . PCRE.compileRegexWithOptions PCRE.noPreludeREOptions oops = error "lp_prelude" @@ -297,7 +297,7 @@ lp_macro_source = formatMacroSource regexType ExclCaptures lp_env lp_env :: MacroEnv-lp_env = preludeEnv `HML.union` HML.fromList+lp_env = PCRE.preludeEnv `HML.union` HML.fromList [ f "user" user_macro , f "pid#tid:" pid_tid_macro , f "access" access_macro@@ -589,4 +589,7 @@ _ -> Nothing where p cs = matchCapture cs >>= parseInteger . capturedText++regexType :: RegexType+regexType = PCRE.regexType \end{code}
examples/re-prep.lhs view
@@ -39,11 +39,9 @@ import System.IO import TestKit import Text.Heredoc-import Text.RE import Text.RE.Replace import Text.RE.TDFA.ByteString.Lazy import qualified Text.RE.TDFA.String as TS-import Text.RE.TestBench import Text.RE.Tools.Grep import Text.RE.Tools.Sed \end{code}@@ -76,6 +74,7 @@ , prg "--help" , prg "[test]" , prg "badges"+ , prg "blog-badge" , prg "pages" , prg "all" , prg "doc (-|<in-file>) (-|<out-file>)"@@ -179,7 +178,7 @@ prepare_tutorial :: MODE -> FilePath -> FilePath -> IO () prepare_tutorial mode fp_in fp_out = LBS.readFile fp_in >>= prep_tutorial_pp mode >>= incld >>=- LBS.writeFile fp_out+ LBS.writeFile fp_out . sortImports where incld = case mode of Doc -> include_code_pp@@ -191,19 +190,23 @@ prep_tutorial_pp mode = sed' $ Select [ LineEdit [re|^%main ${arg}(top|bottom)$|] $ main_ mode- , Function [re|^${fn}(evalme@{%id}) = checkThis ${arg}(@{%string}) \(${ans}([^)]+)\) \$ *${exp}(.*)$|]+ , LineEdit [re|^import *TestKit$|] $ hide mode+ , LineEdit [re|^\{-# OPTIONS_GHC -fno-warn-missing-signatures *#-\}$|] $ hide mode+ , Function [re|^${fn}(evalme@{%id}) += +(checkThis|checkThisWith +@{%id}) +${arg}(@{%string}) +\(${ans}([^)]+)\) +\$ +\(${exp}(.*)\)$|] TOP $ evalme mode+ , Function [re|^${fn}(evalme@{%id}) += +(checkThis|checkThisWith +@{%id}) +${arg}(@{%string}) +\(${ans}([^)]+)\) +\$ +${exp}(.*)$|]+ TOP $ evalme mode , Function [re|^.*$|] TOP $ passthru ] \end{code} \begin{code} evalme :: MODE- -> LineNo- -> Match LBS.ByteString- -> RELocation- -> Capture LBS.ByteString- -> IO (Maybe LBS.ByteString)+ -> LineNo+ -> Match LBS.ByteString+ -> RELocation+ -> Capture LBS.ByteString+ -> IO (Maybe LBS.ByteString) evalme Doc = evalmeDoc evalme (Gen gs) = evalmeGen gs @@ -214,11 +217,12 @@ main_ Doc = delete main_ (Gen gs) = mainGen gs --delete :: LineNo- -> Matches LBS.ByteString- -> IO (LineEdit LBS.ByteString)-delete _ _ = return Delete+hide :: MODE+ -> LineNo+ -> Matches LBS.ByteString+ -> IO (LineEdit LBS.ByteString)+hide Doc = delete+hide (Gen _) = passthru_ \end{code} \begin{code}@@ -243,13 +247,18 @@ evalmeGen gs _ mtch0 _ _ = Just <$> replaceCapturesM replaceMethods ALL f mtch0 where- f mtch loc cap = case locationCapture loc of- 2 -> do- modifyIORef gs (ide:)- return $ Just $ LBS.pack $ show ide- where- ide = LBS.unpack $ captureText [cp|fn|] mtch- _ -> return $ Just $ capturedText cap+ f mtch loc _ =+ case locationCapture loc == arg_i of+ True -> do+ modifyIORef gs (ide:)+ return $ Just $ LBS.pack $ show ide+ where+ ide = LBS.unpack $ captureText [cp|fn|] mtch+ False -> return Nothing++ arg_i = either oops id $ findCaptureID [cp|arg|] $ captureNames mtch0++ oops = error "evalmeGen: confused captures!" \end{code} How are we doing?@@ -297,7 +306,7 @@ \begin{code} mk_list :: [String] -> [LBS.ByteString]-mk_list [] = ["[]"]+mk_list [] = [" []"] mk_list (ide0:ides) = f "[" ide0 $ foldr (f ",") [" ]"] ides where f pfx ide t = (" "<>pfx<>" "<>LBS.pack ide) : t@@ -332,8 +341,8 @@ \end{code} -passthru action----------------+passthru and delete actions+--------------------------- \begin{code} passthru :: LineNo@@ -342,6 +351,16 @@ -> Capture LBS.ByteString -> IO (Maybe LBS.ByteString) passthru _ _ _ _ = return Nothing++passthru_ :: LineNo+ -> Matches LBS.ByteString+ -> IO (LineEdit LBS.ByteString)+passthru_ _ _ = return NoEdit++delete :: LineNo+ -> Matches LBS.ByteString+ -> IO (LineEdit LBS.ByteString)+delete _ _ = return Delete \end{code}
examples/re-sort-imports.lhs view
@@ -65,7 +65,8 @@ putStr $ unlines [ "usage:" , " "++prg++" [test]"- , " "++prg++" <directory>"+ , " "++prg++" check <directory>"+ , " "++prg++" update <directory>" ] \end{code}
examples/re-tests.lhs view
@@ -48,7 +48,6 @@ import Test.Tasty.SmallCheck as SC import TestKit import Text.Heredoc-import Text.RE import qualified Text.RE.PCRE as PCRE import qualified Text.RE.PCRE.ByteString as P_BS import qualified Text.RE.PCRE.ByteString.Lazy as PLBS@@ -66,10 +65,7 @@ import Text.RE.TestBench import Text.RE.Tools.Find import Text.RE.Tools.Sed-import Text.RE.ZeInternals.AddCaptureNames-import Text.RE.ZeInternals.NamedCaptures-import Text.RE.ZeInternals.PreludeMacros-import Text.RE.ZeInternals.Types.CaptureID+import Text.RE.ZeInternals import qualified Text.Regex.PCRE as PCRE_ import qualified Text.Regex.TDFA as TDFA_ @@ -365,7 +361,9 @@ \begin{code} search_replace_tests :: TestTree search_replace_tests = testGroup "SearchReplace"- [ testCase "TDFA.ed/String" $ test id tdfa_eds+ [ testCase "?=~/ [ed_| ... |]" $ "baz bar foobar" @=? "foo bar foobar" T_ST.?=~/ [ed_|foo///baz|] ()+ , testCase "*=~/ [ed_| ... |]" $ "baz bar bazbar" @=? "foo bar foobar" T_ST.*=~/ [ed_|foo///baz|] MultilineSensitive+ , testCase "TDFA.ed/String" $ test id tdfa_eds , testCase "PCRE.ed/String" $ test id pcre_eds , testCase "TDFA.ed/B" $ test B.pack tdfa_eds , testCase "PCRE.ed/B" $ test B.pack pcre_eds@@ -727,7 +725,7 @@ misc_tests = testGroup "Miscelaneous Tests" [ testGroup "CaptureID" [ testCase "CaptureID lookup failure" $ do- ok <- isValidError $ unsafeFindCaptureID [cp|foo|] $ reCaptureNames [re|foo|]+ ok <- isValidError $ unsafe_find_capture_id [cp|foo|] $ reCaptureNames [re|foo|] assertBool "failed" ok ] , testGroup "QQ"@@ -901,6 +899,9 @@ where hdl :: SomeException -> IO Bool hdl se = return $ (length $ show se) `seq` True++unsafe_find_capture_id :: CaptureID -> CaptureNames -> CaptureOrdinal+unsafe_find_capture_id cid = either error id . findCaptureID cid un_either :: Either String a -> a un_either = either error id
examples/re-tutorial-options.lhs view
@@ -1,29 +1,244 @@-The Regex Options Tutorial+The regex Options Tutorial ========================== +Language Options and Imports+-----------------------------++This tutorial is a literate Haskell program whwre we start by specifying+the language pragmas and imports we will need for this module.+ \begin{code} {-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# OPTIONS_GHC -fno-warn-missing-signatures #-} \end{code} +\begin{code}+module Main(main) where+\end{code} +*********************************************************+*+* WARNING: this is generated from pp-tutorial-master.lhs +*+*********************************************************+++For this module we will work with the PCRE nativeoptions which are+based on bit masks, so `Data.Bits` will be needed.++`Text.RE.REOptions` provides the generic regex types and functions for+handling options, regardless of the selected back end.++Note that we import the PCRE `String` APi `Text.RE.PCRE.String` *and*+the general regex PCRE back end, `Text.RE.PCRE`, needed for the the types+and functions is supplies for accessing the PCRE native options. We could+have just imported `Text.RE.PCRE` but it is useful to see which+extra types and functions being used from this module+(they will be qualified with `PCRE.`).++We also import `Text.Regex.PCRE` from the `regex-pcre` package for the+native pcre-regex types and functions themselves.+ \begin{code}-import Prelude.Compat+import Data.Bits import TestKit-import Text.RE.TDFA.String+import qualified Text.RE.PCRE as PCRE+import Text.RE.PCRE.String+import Text.RE.REOptions+import Text.Regex.PCRE \end{code} +Compiling REs with the Complete REOptions+-----------------------------------------++Each `regex-tools` back end — TDFA and PCRE — has it own+complile-time options and execution-time options, called in each case+`CompOption` and `ExecOption`. The SimpleREOptions selected with the+RE parser, e.g., \begin{code}-evalme_TRD_00 = checkThis "evalme_TRD_00" (True) $ ("2016-01-09 2015-12-5 2015-10-05" =~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] :: Bool)+evalme_REO_01 = checkThis "evalme_REO_01" (1) $ countMatches $ "0a\nbb\nFe\nA5" *=~ [reBlockInsensitive|[0-9a-f]{2}$|] \end{code}+configures the RE back end accordingly so that you don't have to,+but you may need full access to your chosen back end's options, in which+case you will need to know about the `REOptions` type, defined by each of+the back ends in terms of the `REOptions_` type of `Text.RE.REOptions`+as follows.+<div class='inlinecodeblock'>+```+type REOptions = REOptions_ RE CompOption ExecOption+```+</div>+(Bear in mind that `RE`, `CompOption` and `ExecOption` are defined+differently in the TDFA and PCRE back ends.) +The `REOptions_` type is defined in `Text.RE.REOptions` as follows: +%include "Text/RE/REOptions.lhs" "data REOptions_"++ * `optionsMacs` contains the macro definitions used to compile+ the REs (see the [test bench tutorial](re-tutorial-testbench.html)+ for details on how to define your own macro environments);++ * `optionsComp` contains the back end compile-time options;++ * `optionsExec` contains the back end execution-time options.++(For more information on the options provided by the back ends see the+decumentation for the `regex-tdfa` and `regex-pcre` packages as+apropriate.)++Each back end provides a function to compile REs from some options and a+string containing the RE as follows:+<div class='inlinecodeblock'>+```+compileRegexWithOptions :: (IsOption o, Functor m, Monad m)+ => o+ -> String+ -> m RE+```+</div>+where `o` is one of the following RE-configuring types:++ * `()` (the unit type), representing the default multi-line+ case-sensitive used with the `re` parser.++ * `SimpleREOptions` (explained in the [main tutorial](re-tutorial.html)),+ which will be converted into the apropriate `CompOption` and+ `ExecOption` for the beck end in question);++ * `CompOption` to directly specify the compile-time options for the back+ end;++ * `ExecOption` to specify the execution-time options for the+ back end;++ * `Macros RE` to specify the alternative macros to use instead of the+ standard environment;++ * `REOptions` to specify all together, the back-end options and the+ macro table to use.++The compilation takes place in a monad to allow for failure. In the following+examples we will use this helper, which will extract the compiled RE using+error to deal with any failures. \begin{code}+check :: Either String a -> a+check = either error id+\end{code}++\begin{code}+evalme_OPT_01 = checkThis "evalme_OPT_01" (1) $ countMatches $ "0a\nbb\nFe\nA5" *=~ check (compileRegexWith BlockInsensitive "[0-9a-f]{2}$")+\end{code}++This will allow you to compile regular expressions when the either the+text to be compiled or the options have been dynamically determined.++If you need to build `SearchReplace` templates then there is an analagous+compilation function for that:++```+compileSearchReplaceWithOptions :: (Monad m,Functor m,IsRegex RE s)+ => REOptions+ -> String+ -> String+ -> m (SearchReplace RE s)+```+++Specifying REOptions with `re_` and `ed_`+-----------------------------------------++If you just need to specify some non-standard options with a static RE,+you can use the `re_` quasi quoter, which yields a function takes an+option type and returns the RE compiled with the given options:+\begin{code}+evalme_REU_01 = checkThis "evalme_REU_01" (1) $ countMatches $ "0a\nbb\nFe\nA5" *=~ [re_|[0-9a-f]{2}$|] BlockInsensitive+\end{code}+Any option `o` such that `IsOption o RE CompOption ExecOption` (i.e.,+any option type accepted by `compileRegex` above) can be used with+`[re_` ... `|]`.++The `[ed_` ... `///` ... `|]` for compiling `SearchReplace` templates+works analagously, yielding a function that takes an option type and+returns the `SearchReplace` template comoiled with those RE options.+++Configuring Native (PCRE) Options+---------------------------------++The function `unpackSimpleREOptions`, used to generate PCRE native+options from the generic `SimpleREOptions` is defined like this.+(We have made some minor organizational changes for this+presentaion, but this is equivalent to the library code used for+`PCRE.unpackSimpleREOptions`.)++\begin{code}+unpackSimpleREOptions :: SimpleREOptions -> PCRE.REOptions+unpackSimpleREOptions sro =+ REOptions+ { optionsMacs = PCRE.prelude -- the standard 'prelude' macro environment+ , optionsComp = comp -- our calculated PCRE compile options+ , optionsExec = defaultExecOpt -- the default PCRE run-time options+ }+ where+ comp =+ wiggle ml compMultiline $+ wiggle ci compCaseless+ defaultCompOpt++ (ml,ci) = case sro of+ MultilineSensitive -> (,) True False+ MultilineInsensitive -> (,) True True+ BlockSensitive -> (,) False False+ BlockInsensitive -> (,) False True++-- set or clear a PCRE option bit according to the+-- Bool in its first argument using the bit mask+-- passed in the second argument+wiggle :: Bits a => Bool -> a -> a -> a+wiggle True m v = v .|. m+wiggle False m v = v .&. complement m+\end{code}++Now we will set up a apecial set of PCRE options based on+`BlockInsensitive`, but with the+[PCRE `DOTALL` option bit](http://pcre.org/pcre.txt) set.++\begin{code}+myOptions :: PCRE.REOptions+myOptions =+ PCRE.defaultREOptions+ { optionsComp = wiggle True compDotAll $ optionsComp biOptions+ }++biOptions :: PCRE.REOptions+biOptions = unpackSimpleREOptions BlockInsensitive+\end{code}++Now we can test `myOptions` with the `[re_| ... |]` quasi quoter as follows.++\begin{code}+evalme_EXA_01 = checkThis "evalme_EXA_01" (True) $ matched $ "0a\nbbxFe&A5 " ?=~ [re_|^([0-9a-f]{2}.){4}$|] myOptions+\end{code}++That test matched, but if we provide just `BlockInsensitive` options set up+in `biOptions` above,++\begin{code}+evalme_EXA_02 = checkThis "evalme_EXA_02" (False) $ matched $ "0a\nbbxFe&A5 " ?=~ [re_|^([0-9a-f]{2}.){4}$|] biOptions+\end{code}++the match fails.++\begin{code} main :: IO () main = runTheTests- [ evalme_TRD_00+ [ evalme_EXA_02+ , evalme_EXA_01+ , evalme_REU_01+ , evalme_OPT_01+ , evalme_REO_01 ] \end{code}
examples/re-tutorial-replacing.lhs view
@@ -1,29 +1,234 @@-The Regex Options Tutorial-==========================+The regex Replacing Tutorial+============================ ++Language Options and Imports+-----------------------------++This tutorial is a literate Haskell program whwre we start by specifying+the language pragmas and imports we will need for this module.+ \begin{code} {-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# OPTIONS_GHC -fno-warn-missing-signatures #-} \end{code} +\begin{code}+module Main(main) where+\end{code} +*********************************************************+*+* WARNING: this is generated from pp-tutorial-master.lhs +*+*********************************************************++ \begin{code}-import Prelude.Compat import TestKit+import Text.RE.Replace import Text.RE.TDFA.String \end{code} +Simple Text Replacement+-----------------------++regex supports the replacement of matched text with alternative text. This+section will cover replacement text specified with templates. More flexible+tools that allow functions calculate the replacement text are covered below.++_Capture_ sub-expressions, whose matched text can be inserted into the+replacement template, can be specified as follows:++ * `$(` ... `)` identifies a capture that can be identified by its+ left-to-right position relative to the other captures in the replacement+ template, with `$1` being used to represent the leftmost capture, `$2` the+ next leftmost capture, and so on;++ * `${foo}(` ... `)` can be used to identify a capture by name. Such captures+ can be identified either by their left-to-right position in the regular+ expression or by `${foo}` in the template.++A function to convert ISO format dates into a UK-format date could be written+thus: \begin{code}-evalme_TRD_00 = checkThis "evalme_TRD_00" (True) $ ("2016-01-09 2015-12-5 2015-10-05" =~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] :: Bool)+uk_dates :: String -> String+uk_dates src =+ replaceAll "${d}/${m}/${y}" $ src *=~ [re|${y}([0-9]{4})-${m}([0-9]{2})-${d}([0-9]{2})|] \end{code}+with+\begin{code}+evalme_RPL_01 = checkThis "evalme_RPL_01" ("09/01/2016 2015-12-5 05/10/2015") $ uk_dates "2016-01-09 2015-12-5 2015-10-05"+\end{code} +The same function written with numbered captures:+\begin{code}+uk_dates' :: String -> String+uk_dates' src =+ replaceAll "$3/$2/$1" $ src *=~ [re|$([0-9]{4})-$([0-9]{2})-$([0-9]{2})|]+\end{code}+with+\begin{code}+evalme_RPL_02 = checkThis "evalme_RPL_02" ("09/01/2016 2015-12-5 05/10/2015") $ uk_dates' "2016-01-09 2015-12-5 2015-10-05"+\end{code}+yielding the same result. +(Most regex conventions use plain parentheses, `(` ... `)`, to mark+captures but we would like to reserve those exclusively for grouping+in regex REs.)+++Matches/Match/Capture+---------------------++The types returned by the `?=~` and `*=~` form the foundations of the+package. Understandingv these simple types is the key to understanding+the package.++The type of `*=~` in this module (imported from+`Text.RE.TDFA.String`) is:+<div class='inlinecodeblock'>+```haskell+(*=~) :: String -> RE -> Matches String+```+</div>+with `Matches` defined in `Text.RE.ZeInternals.Types.Capture` thus:++%include "Text/RE/ZeInternals/Types/Matches.lhs" "^data Matches "++The critical component of the `Matches` type is the `[Match a]` in+`allMatches`, containing the details all of each substring matched by+the RE. The `matchSource` component also retains a copy of the original+search string but the critical information is in `allmatches`.++The type of `?=~` in this module (imported from+`Text.RE.TDFA.String`) is:+<div class='inlinecodeblock'>+```haskell+(?=~) :: String -> RE -> Match String+```+</div>+with `Match` (referenced in the definition of `Matches` above) defined+in `Text.RE.ZeInternals.Types.Capture` thus:++%include "Text/RE/ZeInternals/Types/Match.lhs" "^data Match "++Like `matchesSource` above, `matchSource` retains the original search+string, but also a `CaptureNames` field listing all of the capture+names in the RE (needed by the text replacemnt tools).++But the 'real' content of `Match` is to be found in the `MatchArray`,+enumerating all of the substrings captured by this match, starting with+`0` for the substring captured by the whole RE, `1` for the leftmost+explicit capture in the RE, `2` for the next leftmost capture, and so+on.++Each captured substring is represented by the following `Capture` type:++%include "Text/RE/ZeInternals/Types/Capture.lhs" "^data Capture "++Here we list the whole original search string in `captureSource` and+the text of the sub-string captured in `capturedText`. `captureOffset`+contains the number of characters preceding the captured substring, or+is negative if no substring was captured (which is a different+situation from epsilon, the empty string, being captured).+`captureLength` gives the length of the captured string in+`capturedText`.++The test suite in [examples/re-tests.lhs](re-tests.html) contains extensive+worked-out examples of these `Matches`/`Match`/`Capture` types.+++Using Functions to Replace Text+-------------------------------++Sometimes you will need to process each string captured by an RE with a+function. `replaceAllCaptures` takes a `REContext`, a substitution+function and a `Matches` and applies the function to each captured+substring according to the `REContext`, as we can see in the following+example function to clean up all of the mis-formatted dates in the+argument string, \begin{code}+fixup_dates :: String -> String+fixup_dates src =+ replaceAllCaptures SUB phi $ src *=~ [re|([0-9]+)-([0-9]+)-([0-9]+)|]+ where+ phi _ loc cap = Just $ case locationCapture loc of+ 1 -> fmt 4 $ read s+ 2 -> fmt 2 $ read s+ 3 -> fmt 2 $ read s+ _ -> error "fixup_dates"+ where+ s = capturedText cap++fmt :: Int -> Int -> String+fmt w x = replicate (max 0 $ w - length x_s ) '0' ++ x_s+ where+ x_s = show x++\end{code}+which will fix up our running example+\begin{code}+evalme_RPF_01 = checkThis "evalme_RPF_01" ("2016-01-09 2015-12-05 2015-10-05") $ fixup_dates "2016-01-09 2015-12-5 2015-10-05"+\end{code}++The `replaceAllCaptures` function is of type++%include "Text/RE/ZeInternals/Replace.lhs" "replaceAllCaptures ::"++and the `REContext` and `RELocation` types are defined in+`Text.RE.Replace` as follows,++%include "Text/RE/ZeInternals/Replace.lhs" "^data REContext"++The processing function gets applied to the captures specified by the+`REContext`, which can be directed to process `ALL` of the captures,+including the substring captured by the whole RE and all of the+subsidiary capture, or just the `TOP`, `0` capture that the whole RE+matches, or just the `SUB` (subsidiary) captures, as was the case above.++The substitution function takes the `Match` corresponding to the current+redex being processed, the `RELocation` information specifying redex _n_+redex and capure _i_, and the `Capure` being substituted. Our substitution+function didn't need the `Match` context so it ignored it.++The substition function either return `Nothing` to indicate that no+substitution should be made or the replacement text.++The above fixup function could be extended to enclose whole date in+square brackets by specifing an `ALL` context and a `0` case for the+substitution function.+\begin{code}+fixup_and_reformat_dates :: String -> String+fixup_and_reformat_dates src =+ replaceAllCaptures ALL f $ src *=~ [re|([0-9]+)-([0-9]+)-([0-9]+)|]+ where+ f _ loc cap = Just $ case locationCapture loc of+ 0 -> "["++txt++"]"+ 1 -> fmt 4 $ read txt+ 2 -> fmt 2 $ read txt+ 3 -> fmt 2 $ read txt+ _ -> error "fixup_date"+ where+ txt = capturedText cap+\end{code}+The `fixup_and_reformat_dates` applied to our running example,+\begin{code}+evalme_RPF_02 = checkThis "evalme_RPF_02" ("[2016-01-09] [2015-12-05] [2015-10-05]") $ fixup_and_reformat_dates "2016-01-09 2015-12-5 2015-10-05"+\end{code}++`Text.RE.Replace` provides analagous functions for replacing the+test of a single `Match` returned from `?=~`.+++\begin{code} main :: IO () main = runTheTests- [ evalme_TRD_00+ [ evalme_RPF_02+ , evalme_RPF_01+ , evalme_RPL_02+ , evalme_RPL_01 ] \end{code}
examples/re-tutorial-testbench.lhs view
@@ -1,29 +1,177 @@-The Regex Options Tutorial-==========================+The regex Test-Bench Tutorial+============================= +Language Options and Imports+-----------------------------++This tutorial is a literate Haskell program whwre we start by specifying+the language pragmas and imports we will need for this module.+ \begin{code} {-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE FlexibleContexts #-} {-# OPTIONS_GHC -fno-warn-missing-signatures #-} \end{code} +\begin{code}+module Main(main) where+\end{code} +*********************************************************+*+* WARNING: this is generated from pp-tutorial-master.lhs +*+*********************************************************++ \begin{code}-import Prelude.Compat+import Data.Functor.Identity+import qualified Data.HashMap.Lazy as HML import TestKit+import Text.RE.REOptions+import qualified Text.RE.TDFA as TDFA import Text.RE.TDFA.String+import Text.RE.TestBench \end{code} +Macros and Parsers+------------------++regex supports macros in regular expressions. There are a bunch of+standard macros and you can define your own.++RE macros are enclosed in `@{` ... '}'. By convention the macros in+the standard environment start with a '%'. `@{%date}` will match an+ISO 8601 date, this \begin{code}-evalme_TRD_00 = checkThis "evalme_TRD_00" (True) $ ("2016-01-09 2015-12-5 2015-10-05" =~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] :: Bool)+evalme_MAC_00 = checkThis "evalme_MAC_00" (2) $ countMatches $ "2016-01-09 2015-12-5 2015-10-05" *=~ [re|@{%date}|] \end{code}+picking out the two dates. +See the tables listing the standard macros in the tables folder of+the distribution. +See the log-processor example and the `Text.RE.TestBench` for+more on how you can develop, document and test RE macros with the+regex test bench.+++Adding the Epsilon Macro+------------------------++You can use the regex test bench to add you own macros. As a simple example+we will add an 'epsilon' macro to the standard 'prelude' macro environment.+(See the [`re-nginx-log-processor`](re-nginx-log-processor) for a more+extensive example of macro environments.)++The `@{epsilon}` macro will expand to a RE that matches only the empty+string:+```+.{0}+```++(A use such a seemingly useless RE macro will become apparent in the+test example below.)++Firstly we define a two argument function function to create a `MacroDescriptor`+from:++ 1. the `MacroEnv` macro environment argument will be used to compile+ the macro RE (we don't need it in this instance, of course,+ but we are following a general recipe);++ 2. the `macroId` name of the macro (which is passed into us because+ the calling context need the name of the macro).+ \begin{code}+epsilon_macro :: MacroEnv -> MacroID -> MacroDescriptor+epsilon_macro env mid =+ runTests TDFA.regexType Just samples env mid+ MacroDescriptor+ { macroSource = RegexSource ".{0}" -- the RE to be substituted for the macro+ , macroSamples = map fst samples -- list of string that should match the above macro RE+ , macroCounterSamples = counter_samples -- list of string that should **not** match the above macro RE+ , macroTestResults = [] -- for bookkeeping+ , macroParser = Nothing -- no parser needed for this one!+ , macroDescription = "an epsilon parser, matching the empty string only"+ }+ where+ samples :: [(String,String)]+ samples =+ [ dup ""+ ]+ where+ dup x = (x,x)++ counter_samples =+ [ "not an empty string"+ ]+\end{code}++The compiled `Macros RE` that we will slot into the `REOptions` used to+compile the RE is constructed in two steps. Firstly we provide a function+that takes the @MacroEnv@ that all of the macros will use to build their+REs and returns the augmented `MacroEnv` with the new macro definitions.++This `MacroEnv` is generic and not dependent upon any back end —+none of the macros have been compiled.+\begin{code}+my_env :: MacroEnv -> MacroEnv+my_env env0 = env+ where+ env = env0 `HML.union` HML.fromList+ [ f "epsilon" epsilon_macro+ ]++ f nm mk = (mid, mk env mid)+ where+ mid = MacroID nm+\end{code}++From the `MacroEnv` we compile the macros into a `Macros RE` macro table+that we can insert into an `REOptions` that can be used to compile REs+in the application.+\begin{code}+my_macros :: Macros RE+my_macros = runIdentity $ mkMacros mk TDFA.regexType ExclCaptures $ my_env TDFA.preludeEnv+ where+ mk = maybe oops Identity . TDFA.compileRegexWithOptions TDFA.noPreludeREOptions++ oops = error "my_macros: unexpected RE compilation error"+\end{code}++The `makeREOptions` function can be used to construct an `REOptions`+for compiling REs with `[re_| ... |]` and `[ed_| ... /// ... |]` quasi+quoters.++\begin{code}+myOptions :: TDFA.REOptions+myOptions = TDFA.makeREOptions my_macros+\end{code}++Now we can try out the `@{epsilon}` macro, using it to match nothing!++\begin{code}+evalme_TST_00 = checkThis "evalme_TST_00" (True) $ matched $ "///" ?=~ [re_|^//@{epsilon}/$|] myOptions+\end{code}++Why would we we want to match nothing? To break up three '/' in the RE part+of a `[ed_| ... /// ... |]` `SearchReplace` template.++\begin{code}+evalme_TST_01 = checkThis "evalme_TST_01" ("a <three slashes> replacement example") $ "a <///> replacement example" *=~/ [ed_|<//@{epsilon}/>///<three slashes>|] myOptions+\end{code}++For a more extensive example of macro environments see the+[`re-nginx-log-processor`](re-nginx-log-processor)++\begin{code} main :: IO () main = runTheTests- [ evalme_TRD_00+ [ evalme_TST_01+ , evalme_TST_00+ , evalme_MAC_00 ] \end{code}
examples/re-tutorial-tools.lhs view
@@ -1,29 +1,227 @@-The Regex Options Tutorial-==========================+The Regex Tools Tutorial+======================== +Language Options and Imports+-----------------------------++This tutorial is a literate Haskell program whwre we start by specifying+the language pragmas and imports we will need for this module.+ \begin{code} {-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# OPTIONS_GHC -fno-warn-missing-signatures #-} \end{code} +\begin{code}+module Main(main) where+\end{code} +*********************************************************+*+* WARNING: this is generated from pp-tutorial-master.lhs +*+*********************************************************++ \begin{code}-import Prelude.Compat+import qualified Data.ByteString.Lazy.Char8 as LBS+import Data.List import TestKit+import Text.RE.Replace import Text.RE.TDFA.String+import Text.RE.Tools \end{code} +IsRegex, PCRE and TDFA+----------------------++The `IsRegex re tx` provides regex methods for the RE type `re` (belonging+to either the TDFA or PCRE back end) and a text type `tx` that the `re`+back end accepts. The `Text.RE.TDFA` and `Text.RE.PCRE` API modules provide+functions that work over all the text types, with the following match operators:++```haskell+(*=~) :: IsRegex RE s+ => s+ -> RE+ -> Matches s++(?=~) :: IsRegex RE s+ => s+ -> RE+ -> Match s++(*=~/) :: IsRegex RE s => s -> SearchReplace RE s -> s++(?=~/) :: IsRegex RE s => s -> SearchReplace RE s -> s+```+++General IsRegex Functions+-------------------------++The `IsRegex` class is located in `Text.RE.Tools.IsRegex`:++%include "Text/RE/ZeInternals/Types/IsRegex.lhs" "^class Replace s => IsRegex re s"++Using these functions you can write your own regex tools. As a trivial example+we will define fully overloaded regex match operators as follows. \begin{code}-evalme_TRD_00 = checkThis "evalme_TRD_00" (True) $ ("2016-01-09 2015-12-5 2015-10-05" =~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] :: Bool)+(?=~%) :: IsRegex re s => s -> re -> Match s+(?=~%) = flip matchOnce++(*=~%) :: IsRegex re s => s -> re -> Matches s+(*=~%) = flip matchMany \end{code} +\begin{code}+evalme_MYO_01 = checkThis "evalme_MYO_01" (True) $ matched $ (LBS.pack "2016-01-09 2015-12-5 2015-10-05") ?=~% [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|]+\end{code}+\begin{code}+evalme_MYO_02 = checkThis "evalme_MYO_02" (2) $ countMatches $ (LBS.pack "2016-01-09 2015-12-5 2015-10-05") *=~% [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|]+\end{code} +`regex` provides some classic tools that have quickly proven themselves+in the examples and scripts used to maintain regex itself.+++The regex Tools+---------------++The classic tools assocciated with regular expressions have inspired some+regex conterparts.++ * [Text.RE.Tools.Grep](Grep.html): takes a regular expression and a+ file or lazy ByteString (depending upon the variant) and returns all of the+ matching lines.++ * [Text.RE.Tools.Lex](Lex.html): takes an association list of REs and+ token-generating functions and the input text and returns a list of tokens.+ This should never be used where performance is important (use Alex),+ except as a development prototype.++ * [Text.RE.Tools.Sed](Sed.html) using [Text.RE.Tools.Edit](Edit.html):+ takes an association list of regular expressions and substitution actions,+ some input text and invokes the associated action on each line of the file+ that matches one of the REs, substituting the text returned from the action+ in the output stream.++ * [Text.RE.Tools.Find](Find.html): scans a directory tree in the+ file system executing an action against all of the files that match+ RE.++These tools are built on top of the core library and act as good examples+of how to use the regex library as well as useful tools.++The following sections will present some of the internal library code+used to build the tools as well as some code from the example programs.+These fragments work best as starting points for studying these tools.+++Sed and Edit+------------++`Edits` scripts are applied to each line of the text by the `sed`+functions.++%include "Text/RE/Tools/Edit.lhs" "data Edits"++`sed'` applies the script in its first argument to each line in the text+in its second argument.++%include "Text/RE/Tools/Sed.lhs" "sed' ::"++The `sed'` function is used to build the include processor in the+[`TestKit`](TestKit) utility modules used by the example scripts and+programs. To filter lines to exclude the `grepFilter` function is used.++%include "examples/TestKit.lhs" "include ::"+++Grep+----++The `grepFilter` function takes an RE and a text and returns+the result of matching the RE to every line in the file.++%include "Text/RE/Tools/Grep.lhs" "grepFilter ::"++%include "Text/RE/Tools/Grep.lhs" "^data Line"++The `sortImports` utility in the [`TestKit`](TestKit) utility module+used by the scripts and example programs. It uses `grep` to sort all of+the imports by the name of the module in a single block located at the+position of the first import statement in the module, where each import+statement is in a standard form matched by the regex+```haskell+[re|^import +(qualified )? *${mod}([^ ].*)$|]+```++We have reproduced `sortImports` under the name `sortImports_` here. \begin{code}+sortImports_ :: LBS.ByteString -> LBS.ByteString+sortImports_ lbs =+ LBS.unlines $ map (matchesSource . getLineMatches) $+ hdr ++ sortBy cMp bdy+ where+ cMp ln1 ln2 = case (extr ln1,extr ln2) of+ (Nothing,Nothing) -> EQ+ (Nothing,Just _ ) -> GT+ (Just _ ,Nothing) -> LT+ (Just x ,Just y) -> compare x y++ extr ln = case allMatches $ getLineMatches ln of+ mtch:_ -> mtch !$$? [cp|mod|]+ _ -> Nothing++ (hdr,bdy) = span (not . anyMatches . getLineMatches) lns+ lns = grepFilter rex lbs+ rex = [re|^import +(qualified )? *${mod}([^ ].*)$|]+\end{code}++\begin{code}+evalme_GRP_01 = checkThisWith packLBS "evalme_GRP_01" ("-- preamble\nimport Data.List\nimport qualified Data.Text as T\n-- done\n") $ sortImports_ $ LBS.pack "-- preamble\nimport qualified Data.Text as T\nimport Data.List\n-- done\n"+\end{code}+++Lex+---++The Lex toolkit can be used for quickly knocking together+scanners that do not need to be efficient.++%include "Text/RE/ZeInternals/Tools/Lex.lhs" "alex ::"++It has been used in the library to scan REs so that the captures can+be picked out, numbered and that number associated with a name where one+has been given.++%include "Text/RE/ZeInternals/NamedCaptures.lhs" "scan ::"+++Find+----++The `findMatches_` function lists all of the files in a directort tree+that match an RE.++%include "Text/RE/Tools/Find.lhs" "findMatches_ ::"++It is used by the [`re-sort-imports`](re-sort-imports) program to discover+all of the Haskell scripts in the regex source tree and sort their import+statements into a standard order (ultimately using the+above-mentioned `sortImport` function).++%include "examples/re-sort-imports.lhs" "sort_r ::"+++\begin{code} main :: IO () main = runTheTests- [ evalme_TRD_00+ [ evalme_GRP_01+ , evalme_MYO_02+ , evalme_MYO_01 ] \end{code}
examples/re-tutorial.lhs view
@@ -1,61 +1,30 @@-The Regex Tutorial+The regex Tutorial ================== -This is a literate Haskell programme lightly processed to produce this-web presentation and also to generate a test suite that verifies that-each of the example calculations are generating the expected results.-You can load it into ghci and try out the examples either by running-_ghci_ itself from the root folder of the regex package:-```bash-ghci examples/re-tutorial.lhs-```-or using `cabal repl`:-```-cabal configure --enable-tests-cabal repl examples/re-tutorial.lhs-```--Depending upon how you have configured and run `ghci` you may need to-set one of _ghci_'s interctive settings — the topic of the next-section.+This tutorial is a self-testing literate Haskell programme introducing+the vanilla API of the [regex package](http://hs.regex.uk). There+are other tutorials for explaining the more specialist aspects of regex+and you can load them into into you Haskell REPL of choice: see the+[regex Tutorials page](http://tutorial.regex.uk) for details. -Setting Up: The Pragmas--------------------------Haskell programs typically start with a few compiler pragmas to switch-on the language extensions needed by the module. Because regex uses-Template Haskell to check regular expressions at compile time `QuasiQuotes`-should be enabled.+Language Pragmas+---------------- +The first thing you will have to do is enable `QuasiQuotes` as regex+uses them to check that REs are well-formed at compile time. \begin{code}-{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE QuasiQuotes #-}+{-# OPTIONS_GHC -fno-warn-missing-signatures #-} \end{code}--Use this command to configure ghci accordingly (not necessary if you-have launched ghci with `cabal repl`):+If you are trying out examples interactively at the ghci prompt then you+will need ``` :seti -XQuasiQuotes ``` -Because we are mimicking the REPL in this tutorial we will leave off the type-signatures on the example calculations and disable the compiler-warnings about missing type signatures.-\begin{code}-{-# OPTIONS_GHC -fno-warn-missing-signatures #-}-\end{code}--This pragma is a just technical pragma, combined with the-`Prelude.Compat` import below used to avoid certain warnings while-comiling against multiple versions of the compiler. It can be safely-ignored.-\begin{code}-{-# LANGUAGE NoImplicitPrelude #-}-\end{code}---Loading Up: The Imports------------------------+Importing the API+----------------- \begin{code} module Main(main) where@@ -67,259 +36,147 @@ * ********************************************************* -We have two things to consider in the import to access the regex-goodies, which will take the form:-```haskell-import Text.RE.<regex-flavour>.<text-type>?-``` - * Which [flavour of regular expressions](https://wiki.haskell.org/Regular_expressions) do I need?- + `PCRE` : [Perl-style](https://en.wikibooks.org/wiki/Regular_Expressions/Perl-Compatible_Regular_Expressions) regular expressions;- + `TDFA`: [Posix-style](https://en.wikipedia.org/wiki/Regular_expression#POSIX_extended) regular expressions.-- * And which type of text am I matching?- + `String` : low-performing, classic Haskell strings;- + `ByteString` : raw bytestrings;- + `ByteString.Lazy` : raw lazy bytestrings;- + `Text`: efficient text (currently available for `TDFA` only);- + `Text.Lazy` : efficient, lazy text (currently available for- `TDFA` only);- + polymorphic: if you need matching operators that work with all- available text types then do not specify the `<text-type>` in- the import path.--For this tutorial we will use classic Haskell strings but any application-dealing with bulk text will probably want to choose one of the other-options.-\begin{code}-import Control.Applicative-import Data.Maybe-import qualified Data.Text as T-import Prelude.Compat-import TestKit-import Text.Printf-import Text.RE.REOptions-import Text.RE.Replace-import Text.RE.TDFA.String-\end{code}-If you are predominantly matching against a single type in your module-then you will probably find it more convenient to use the relevant module-rather than than the more polymorphic opertors but it is really a-matter of convenience.+Before importing the `regex` API into your Haskell script you will need+to answer two questions: -We will also need access to a small selection of common libraries for-our examples.-\begin{code}-\end{code}+ 1. Which flavour of REs do I need? If you need Posix REs then the `TDFA`+ is for you, otherwise it is the PCRE back end, which is housed in+ a seperate `regex-with-pcre` package. -And finally we a special edition of the prelude (see the commentary for-the pragma section above) and a small specail toolkit will be used to help-manage the example calculations.-\begin{code}-\end{code}-This allows simple calculations to be defined stylistically-in the source program, presented as calculations when rendered-in HTML and tested that they have the expected result.-\begin{code}-evalme_LOA_00 = checkThis "evalme_LOA_00" (0) $ length []-\end{code}-This trivial example calculation will be tested for zero-ness.+ 2. Which Haskell type is being used for the text I need to match? This+ can influence as, at the time of writing, the `PCRE` `regex` back end+ [does not support the`Text` types](https://github.com/iconnect/regex/issues/58). +The import statement will in general look like this+```+ import Text.RE.<back-end>.<text-type>+``` -Matching with the regex-base Operators---------------------------------------+As we have no interest in Posix/PCRE distinctions or performance here,+we have chosen to work with the `TDFA` back end with `String` types. -regex supports the regex-base polymorphic match operators. Used in a-`Bool` context `=~` will evaluate to True iff the string on the left matches-the RE on the right. \begin{code}-evalme_TRD_00 = checkThis "evalme_TRD_00" (True) $ ("2016-01-09 2015-12-5 2015-10-05" =~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] :: Bool)-\end{code}-Note that we enclose the RE itself in `[re|` ... `|]` quasi quote brackets,-allowing the compiler to run some regex code at compile time to verify that-the RE conforms to the correct syntax for the chosen RE flavour of choice-(`TDFA` in this case). The above expression should evaluate to `True` as the-string contains a matching sub-string.--Used in an `Int` context `=~` will count the number of matches in the target string.-\begin{code}-evalme_TRD_01 = checkThis "evalme_TRD_01" (2) $ ("2016-01-09 2015-12-5 2015-10-05" =~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] :: Int)-\end{code}--To determine the string that has matched the monadic `=~~` operator can be used-in a `Maybe` context.-\begin{code}-evalme_TRD_02 = checkThis "evalme_TRD_02" (Just "2016-01-09") $ ("2016-01-09 2015-12-5 2015-10-05" =~~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] :: Maybe String)-\end{code}--A `=~` in a `[[String]]` extracts all of the matched substrings:-\begin{code}-evalme_TRD_04 = checkThis "evalme_TRD_04" ([["2016-01-09"],["2015-10-05"]]) $ ("2016-01-09 2015-12-5 2015-10-05" =~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] :: [[String]])+import TestKit+import Text.RE.TDFA.String \end{code} -regex provides special operators and types for extracting the first-match or all of the non-overlapping substrings matching a regular expression-which provide a little more structure that the flexible, venerable regex-base-match operators.+You could also import `Text.RE.TDFA` or `Text.RE.PCRE` to get an API+in which the operators are overloaded over all text types accepted by+each of these back ends: see the [Tools Tutorial](re-tutorial-tools.html)+for details. -Single Matches with `?=~`+Single `Match` with `?=~` ------------------------- -regex also provides two matching operators: one for looking for the first+The regex API provides two matching operators: one for looking for the first match in its search string and the other for finding all of the matches. The first-match operator, `?=~`, yields the result of attempting to find the first-match. (It's result type will be explained below.) The boolean `matched`-function can be used to test whether a match was found.+match.+```+(?=~) :: String -> RE -> Match String+```+The boolean `matched` function,+```+matched :: Match a -> Bool+```+can be used to test whether a match was found: \begin{code} evalme_SGL_01 = checkThis "evalme_SGL_01" (True) $ matched $ "2016-01-09 2015-12-5 2015-10-05" ?=~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] \end{code} -To get the matched text use `matchText`, which returns `Nothing` if no match was-found in the search string.+To get the matched text use `matchText`,+```+matchedText :: Match a -> Maybe a+```+which returns `Nothing` if no match was found in the search string: \begin{code} evalme_SGL_02 = checkThis "evalme_SGL_02" (Just "2016-01-09") $ matchedText $ "2016-01-09 2015-12-5 2015-10-05" ?=~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] \end{code}+\begin{code}+evalme_SGL_03 = checkThis "evalme_SGL_03" (Nothing) $ matchedText $ "2015-12-5" ?=~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|]+\end{code} -Multiple Matches with `*=~`----------------------------+Multiple `Matches` with `*=~`+----------------------------- -Use `*=~` to locate all of the non-overlapping substrings that matches a RE.-`anyMatches` will return `True` iff any matches are found (and they will be).+Use `*=~` to locate all of the non-overlapping substrings that match a RE,+```+(*=~) :: String -> RE -> Matches String+anyMatches :: Matches a -> Bool+```+`anyMatches` can be used to determine if any matches were found \begin{code} evalme_MLT_01 = checkThis "evalme_MLT_01" (True) $ anyMatches $ "2016-01-09 2015-12-5 2015-10-05" *=~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] \end{code}--`countMatches` will tell us how many sub-strings matched (2).+and `countMatches` will tell us how many sub-strings matched: \begin{code} evalme_MLT_02 = checkThis "evalme_MLT_02" (2) $ countMatches $ "2016-01-09 2015-12-5 2015-10-05" *=~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] \end{code}- `matches` will return all of the matches.+```+matches :: Natches a -> [a]+``` \begin{code} evalme_MLT_03 = checkThis "evalme_MLT_03" (["2016-01-09","2015-10-05"]) $ matches $ "2016-01-09 2015-12-5 2015-10-05" *=~ [re|[0-9]{4}-[0-9]{2}-[0-9]{2}|] \end{code} -Simple Text Replacement--------------------------regex supports the replacement of matched text with alternative text. This-section will cover replacement text specified with templates. More flexible-tools that allow functions calculate the replacement text are covered below.--_Capture_ sub-expressions, whose matched text can be inserted into the-replacement template, can be specified as follows:-- * `$(` ... `)` identifies a capture that can be identified by its- left-to-right position relative to the other captures in the replacement- template, with `$1` being used to represent the leftmost capture, `$2` the- next leftmost capture, and so on;+The `regex` Macros and Parsers+------------------------------ - * `${foo}(` ... `)` can be used to identify a capture by name. Such captures- can be identified either by their left-to-right position in the regular- expression or by `${foo}` in the template.+regex supports macros in regular expressions. There are a bunch of+standard macros that you can just use, and you can define your own. -A function to convert ISO format dates into a UK-format date could be written-thus:-\begin{code}-uk_dates :: String -> String-uk_dates src =- replaceAll "${d}/${m}/${y}" $ src *=~ [re|${y}([0-9]{4})-${m}([0-9]{2})-${d}([0-9]{2})|]-\end{code}-with+RE macros are enclosed in `@{` ... '}'. By convention the macros in+the standard environment start with a '%'. `@{%date}` will match an+ISO 8601 date, this \begin{code}-evalme_RPL_01 = checkThis "evalme_RPL_01" ("09/01/2016 2015-12-5 05/10/2015") $ uk_dates "2016-01-09 2015-12-5 2015-10-05"+evalme_MAC_00 = checkThis "evalme_MAC_00" (2) $ countMatches $ "2016-01-09 2015-12-5 2015-10-05" *=~ [re|@{%date}|] \end{code}+will pick out the two dates. -The same function written with numbered captures:-\begin{code}-uk_dates' :: String -> String-uk_dates' src =- replaceAll "$3/$2/$1" $ src *=~ [re|$([0-9]{4})-$([0-9]{2})-$([0-9]{2})|]-\end{code}-with+There are also parsing functions for analysing the matched text. The+`@{%string}` macro will match quoted strings (in which double quotes can be+escaped with backslashes in the usual way) and its companion `parseString`+function will extract the string that was being quoted, interpreting any+escaped double quotes: \begin{code}-evalme_RPL_02 = checkThis "evalme_RPL_02" ("09/01/2016 2015-12-5 05/10/2015") $ uk_dates' "2016-01-09 2015-12-5 2015-10-05"+evalme_MAC_01 = checkThisWith convertMaybeTextList "evalme_MAC_01" ([Just "foo",Just "bar", Just "\""]) $ map parseString $ matches $ "\"foo\", \"bar\" and a quote \"\\\"\"" *=~ [re|@{%string}|] \end{code}-yielding the same result. -(Most regex conventions use plain parentheses, `(` ... `)`, to mark-captures but we would like to reserve those exclusively for grouping-in regex REs.)+See the [macro tables page](http://macros.regex.uk) for details of the standard macros and their parsers. +See the [testbench tutorial](re-tutorial-testbench.html) for more on how+you can develop, document and test RE macros with the regex test bench. -Matches/Match/Capture---------------------- -The types returned by the `?=~` and `*=~` form the foundations of the-package. Understandingv these simple types is the key to understanding-the package.--The type of `*=~` in this module (imported from-`Text.RE.TDFA.String`) is:-<div class='inlinecodeblock'>-```-(*=~) :: String -> RE -> Matches String-```-</div>-with `Matches` defined in `Text.RE.ZeInternals.Types.Capture` thus:--%include "Text/RE/ZeInternals/Types/Matches.lhs" "^data Matches "--The critical component of the `Matches` type is the `[Match a]` in-`allMatches`, containing the details all of each substring matched by-the RE. The `matchSource` component also retains a copy of the original-search string but the critical information is in `allmatches`.--The type of `?=~` in this module (imported from-`Text.RE.TDFA.String`) is:-<div class='inlinecodeblock'>-```-(?=~) :: String -> RE -> Match String-```-</div>-with `Match` (referenced in the definition of `Matches` above) defined-in `Text.RE.ZeInternals.Types.Capture` thus:--%include "Text/RE/ZeInternals/Types/Match.lhs" "^data Match "--Like `matchesSource` above, `matchSource` retains the original search-string, but also a `CaptureNames` field listing all of the capture-names in the RE (needed by the text replacemnt tools).--But the 'real' content of `Match` is to be found in the `MatchArray`,-enumerating all of the substrings captured by this match, starting with-`0` for the substring captured by the whole RE, `1` for the leftmost-explicit capture in the RE, `2` for the next leftmost capture, and so-on.--Each captured substring is represented by the following `Capture` type:--%include "Text/RE/ZeInternals/Types/Capture.lhs" "^data Capture "+Search and Replace+------------------ -Here we list the whole original search string in `captureSource` and-the text of the sub-string captured in `capturedText`. `captureOffset`-contains the number of characters preceding the captured substring, or-is negative if no substring was captured (which is a different-situation from epsilon, the empty string, being captured).-`captureLength` gives the length of the captured string in-`capturedText`.+If you need to edit a string then `SearchReplace` `[ed|` ... `|]`+templates can be used with `?=~/` to replace a single instance or+`*=~/` to replace all matching instances. -The test suite in [examples/re-tests.lhs](re-tests.html) contains extensive-worked-out examples of these `Matches`/`Match`/`Capture` types.+\begin{code}+evalme_SRP_00 = checkThis "evalme_SRP_00" ("0x0000: 40AA fab0") $ "0000 40AA fab0" ?=~/ [ed|${adr}([0-9A-Fa-f]{4}):?///0x${adr}:|]+\end{code}+\begin{code}+evalme_SRP_01 = checkThis "evalme_SRP_01" ("0x0000: 0x40AA 0xfab0") $ "0000: 40AA fab0" *=~/ [ed|[0-9A-Fa-f]{4}///0x$0|]+\end{code} -Simple REOptions-----------------+Specifying Options+------------------ By default regular expressions are of the multi-line case-sensitive-variety so this query+variety so this \begin{code} evalme_SOP_01 = checkThis "evalme_SOP_01" (2) $ countMatches $ "0a\nbb\nFe\nA5" *=~ [re|[0-9a-f]{2}$|] \end{code}-finds 2 matches, the '$' anchor matching each of the newlines, but only+will find 2 matches, the '$' anchor matching each of the newlines, but only the first two lowercase hex numbers matching the RE. The case sensitivity and multiline-ness can be controled by selecting alternative parsers. @@ -359,473 +216,103 @@ \end{code} -Using Functions to Replace Text--------------------------------+Compiling and Escaping+---------------------- -Sometimes you will need to process each string captured by an RE with a-function. `replaceAllCaptures` takes a `REContext`, a substitution-function and a `Matches` and applies the function to each captured-substring according to the `REContext`, as we can see in the following-example function to clean up all of the mis-formatted dates in the-argument string,-\begin{code}-fixup_dates :: String -> String-fixup_dates src =- replaceAllCaptures SUB phi $ src *=~ [re|([0-9]+)-([0-9]+)-([0-9]+)|]- where- phi _ loc cap = Just $ case locationCapture loc of- 1 -> printf "%04d" (read s :: Int)- 2 -> printf "%02d" (read s :: Int)- 3 -> printf "%02d" (read s :: Int)- _ -> error "fixup_dates"- where- s = capturedText cap-\end{code}-which will fix up our running example+It is possible to compile a dynamically aquired RE string at run-time using+`compileRegex`:+```+compileRegex :: (Functor m, Monad m) => String -> m RE+``` \begin{code}-evalme_RPF_01 = checkThis "evalme_RPF_01" ("2016-01-09 2015-12-05 2015-10-05") $ fixup_dates "2016-01-09 2015-12-5 2015-10-05"+evalme_CPL_01 = checkThis "evalme_CPL_01" (["2016-01-09","2015-10-05"]) $ matches $ "2016-01-09 2015-12-5 2015-10-05" *=~ (either error id $ compileRegex "[0-9]{4}-[0-9]{2}-[0-9]{2}") \end{code} -The `replaceAllCaptures` function is of type--%include "Text/RE/ZeInternals/Replace.lhs" "replaceAllCaptures ::"--and the `REContext` and `RELocation` types are defined in-`Text.RE.Replace` as follows,--%include "Text/RE/ZeInternals/Replace.lhs" "^data REContext"--The processing function gets applied to the captures specified by the-`REContext`, which can be directed to process `ALL` of the captures,-including the substring captured by the whole RE and all of the-subsidiary capture, or just the `TOP`, `0` capture that the whole RE-matches, or just the `SUB` (subsidiary) captures, as was the case above.--The substitution function takes the `Match` corresponding to the current-redex being processed, the `RELocation` information specifying redex _n_-redex and capure _i_, and the `Capure` being substituted. Our substitution-function didn't need the `Match` context so it ignored it.+These will compile the RE using the default multiline, case-sensitive options,+but you can specify the options dynamically using `compileRegexWith`:+```+compileRegexWith :: (Functor m, Monad m) => SimpleREOptions -> String -> m RE+```+where `SimpleREOptions` is a simple enumerated type. -The substition function either return `Nothing` to indicate that no-substitution should be made or the replacement text.+%include "Text/RE/REOptions.lhs" "^data SimpleREOptions" -The above fixup function could be extended to enclose whole date in-square brackets by specifing an `ALL` context and a `0` case for the-substitution function. \begin{code}-fixup_and_reformat_dates :: String -> String-fixup_and_reformat_dates src =- replaceAllCaptures ALL f $ src *=~ [re|([0-9]+)-([0-9]+)-([0-9]+)|]- where- f _ loc cap = Just $ case locationCapture loc of- 0 -> printf "[%s]" txt- 1 -> printf "%04d" (read txt :: Int)- 2 -> printf "%02d" (read txt :: Int)- 3 -> printf "%02d" (read txt :: Int)- _ -> error "fixup_date"- where- txt = capturedText cap-\end{code}-The `fixup_and_reformat_dates` applied to our running example,-\begin{code}-evalme_RPF_02 = checkThis "evalme_RPF_02" ("[2016-01-09] [2015-12-05] [2015-10-05]") $ fixup_and_reformat_dates "2016-01-09 2015-12-5 2015-10-05"+evalme_CPL_02 = checkThis "evalme_CPL_02" (["2016-01-09","2015-10-05"]) $ matches $ "2016-01-09 2015-12-5 2015-10-05" *=~ (either error id $ compileRegexWith MultilineSensitive "[0-9]{4}-[0-9]{2}-[0-9]{2}") \end{code} -`Text.RE.Replace` provides analagous functions for replacing the-test of a single `Match` returned from `?=~`.---Macros and Parsers---------------------regex supports macros in regular expressions. There are a bunch of-standard macros and you can define your own.--RE macros are enclosed in `@{` ... '}'. By convention the macros in-the standard environment start with a '%'. `@{%date}` will match an-ISO 8601 date, this-\begin{code}-evalme_MAC_00 = checkThis "evalme_MAC_00" (2) $ countMatches $ "2016-01-09 2015-12-5 2015-10-05" *=~ [re|@{%date}|]-\end{code}-picking out the two dates.--See the tables listing the standard macros in the tables folder of-the distribution.--See the log-processor example and the `Text.RE.TestBench` for-more on how you can develop, document and test RE macros with the-regex test bench.---Compiling REs with the Complete REOptions--------------------------------------------Each type of RE — TDFA and PCRE — has it own complile-time-options and execution-time options, called in each case `CompOption` and-`ExecOption`. The above simple options selected with the RE-parser (`reMultilineSensitive`, etc.) configures the RE backend-accordingly so that you don't have to, but you may need full access to-you chosen back end's options, or you may need to supply a different-set of macros to those provided in the standard environment. In which-case you will need to know about the `REOptions` type, defined by each of-the back ends in terms of the `REOptions_` type of `Text.RE.REOptions`-as follows.-<div class='inlinecodeblock'>+If you need to compile `SearchReplace` templates for use with `?=~/` and+`*=~/` then the `compileSearchReplace` and `compileSearchReplaceWith`, ```-type REOptions = REOptions_ RE CompOption ExecOption+compileSearchReplace :: (Monad m, Functor m, IsRegex RE s) => String -> String -> m (SearchReplace RE s)+compileSearchReplaceWith :: (Monad m, Functor m, IsRegex RE s) => SimpleREOptions -> String -> String -> m (SearchReplace RE s) ```-</div>-(Bear in mind that `CompOption` and `ExecOption` will be different-types for each back end.)--The `REOptions_` type is defined in `Text.RE.REOptions` as follows:--%include "Text/RE/REOptions.lhs" "data REOptions_"-- * `optionsMode` is an experimental feature that controls the RE- parser.-- * `optionsMacs` contains the macro definitions used to compile- the REs (see above Macros section);-- * `optionsComp` contains the back end compile-time options;-- * `optionsExec` contains the back end execution-time options.+work analagously to `compileRegex` and `compileRegexWith`, with the RE+and replacement template (either side of the '///' in the `[ed|...///...|]`+quasi quoters) being passed into these functions in two separate strings,+to compile to the `SearchReplace` type expected by the `?=~/` and `*=~/`+operators. -(For more information on the options provided by the back ends see the-decumentation for `regex-tdfa` and `regex-pcre` as apropriate.)+%include "Text/RE/ZeInternals/Types/SearchReplace.lhs" "^data SearchReplace" -Each backend provides a function to compile REs from some options and a-string containing the RE as follows:-<div class='inlinecodeblock'>+The `escape` and `escapeWith` functions are special compilers that compile+a string into a RE that should match itself, which is assumed to be embedded+in a complex RE to be compiled. ```-compileRegex :: ( IsOption o RE CompOption ExecOption- , Functor m- , Monad m- )- => o- -> String- -> m RE+escape :: (Functor m, Monad m) => (String->String) -> String -> m RE ```-</div>-where `o` is some type that is recognised as a type that can configure-REs. Your configuration-type options are:-- * `()` (the unit type) means just use the default multi-line- case-sensitive that we get with the `re` parser.-- * `SimpleREOptions` this is just a simple enum type that we use to- encode the standard options:--%include "Text/RE/REOptions.lhs" "^data SimpleREOptions"-- * `Mode`: you can specify the parser mode;-- * `Macros RE`: you can specify the macros use instead of the standard- environment;-- * `CompOption`: you can specify the compile-time options for the back- end;-- * `ExecOption`: you can specify the execution-time options for the- back end;-- * `REOptions`: you can specify all of the options.--The compilation may fail so it is expressed monadically. For the-following examples we will use the following helper to just `error`-the failure.+The function pased in the first argument to `escape` takes the RE string+that will match the string passed in the second argument and yields the+RE to be compiled, which is returned from the parsing action. \begin{code}-check_for_failure :: Either String a -> a-check_for_failure = either error id+evalme_CPL_03 = checkThis "evalme_CPL_03" ("foobar") $ "fooe{0}bar" *=~/ SearchReplace (either error id $ escape id "e{0}") "" \end{code} -\begin{code}-evalme_OPT_00 = checkThis "evalme_OPT_00" (2) $ countMatches $ "2016-01-09 2015-12-5 2015-10-05" *=~ check_for_failure (compileRegex "@{%date}")-\end{code}-\begin{code}-evalme_OPT_01 = checkThis "evalme_OPT_01" (1) $ countMatches $ "0a\nbb\nFe\nA5" *=~ check_for_failure (compileRegexWith BlockInsensitive "[0-9a-f]{2}$")-\end{code} -This will allow you to compile regular expressions when the either the-text to be compiled or the options have been dynamically determined.---Specifying REOptions with `re_`------------------------------+The Classic regex-base Match Operators+-------------------------------------- -If you just need to specify some non-standard options while statically-checking the validity of the RE (with the default options) then you can-use the `re_` parser:+The original `=~` and `=~~` match operators are still available for+those that have mastered them. \begin{code}-evalme_REU_01 = checkThis "evalme_REU_01" (1) $ countMatches $ "0a\nbb\nFe\nA5" *=~ [re_|[0-9a-f]{2}$|] BlockInsensitive+evalme_CLC_01 = checkThis "evalme_CLC_01" (True ) $ ("bar" =~ [re|(foo|bar)|] :: Bool) \end{code}-Any option `o` such that `IsOption o RE CompOption ExecOption` (i.e.,-any option type accepted by `compileRegex` above) can be used with-`[re_` ..`|]`.---The Tools: 'grep', 'lex' and 'sed'-------------------------------------The classic tools assocciated with regular expressions have inspired some-regex conterparts.-- * [Text.RE.Tools.Grep](Grep.html): takes a regular expression and a- file or lazy ByteString (depending upon the variant) and returns all of the- matching lines. (Used in the [include](re-include.html) example.)-- * [Text.RE.Tools.Lex](Lex.html): takes an association list of REs and- token-generating functions and the input text and returns a list of tokens.- This should never be used where performance is important (use Alex),- except as a development prototype (used internally in- [Text.RE.ZeInternals.NamedCaptures](NamedCaptures.html)).-- * [Text.RE.Tools.Sed](Sed.html) using [Text.RE.Tools.Edit](Edit.html):- takes an association list of regular expressions and substitution actions,- some input text and invokes the associated action on each line of the file- that matches one of the REs, substituting the text returned from the action- in the output stream. (Used in the [include](re-include.html),- [gen-modules](re-gen-modules.html),- [log-processor](re-nginx-log-processor.html) and [tutorial-pp](re-prep)- examples.)---The Examples---------------The remaining sections have been given over to various standalone-examples. All bar the first are taken from the package itself, each-contributing to either the API or the tools used to prepare the-documentation and test suites.---Example: log processor: development with macros--------------------------------------------------To test regex at scale — which is to say, developing with-relatively complex REs —-[a preprocessor](re-nginx-log-processor.html) for parsing NGINX access-and error logs has been written. Each line of input may be either a line-from an NGINX access log or the event log, producing a standard-format-event log on the output.--As a taster, here is the main script, where each type of line is-recognised by a high-level macro.--%include "examples/re-nginx-log-processor.lhs" "script ::"--Thes macros are based on the standard macros, using-`Text.RE.TestBench` to build the up into the above high-level-scanners with the apropriate-[tests and documentation](https://github.com/iconnect/regex/tree/master/tables).--The RE for recognising the access-log lines is built up here.--%include "examples/re-nginx-log-processor.lhs" "access_re ::"--(N.B., The Test Bench currently requires that we write our REs in Haskell-strings.)--See [the log-processor program sources](re-nginx-log-processor.html) for details.---Example: Scanning REs: Named Captures----------------------------------------This package needs to recognise all captures in a regular expression so-that it can associate the named captures with their cature ordinal.--Here is the prototype scanner.--%include "Text/RE/ZeInternals/NamedCaptures.lhs" "scan ::"--Once the package has stabilised it should be rewritten with Alex.--See [Text.RE.ZeInternals.NamedCaptures](NamedCaptures.html) for-details.---Anti-Example: Scanning REs in the TestBench----------------------------------------------The [Text.RE.ZeInternals.TestBench](TestBench.html) contains an almost-identical parser to the above, written with recursive functions.--%include "Text/RE/ZeInternals/TestBench.lhs" "scan_re ::"--Once some technical issues have been ersolved it will use the above-scanner in [Text.RE.ZeInternals.NamedCaptures](NamedCaptures.html).---Example: filename analysis-----------------------------The preprocessor used to prepare the literate programs for this-package's website uses the following 'gen_all' diriver which uses-REs to analyse file paths.--%include "examples/re-prep.lhs" "^gen_all ::"--See [examples/re-prep.lhs](re-prep.html)---Example: parsing RE macros-----------------------------The regex RE macros are parsed with code that looks similar to-this.- \begin{code}--- | expand the @{..} macos in the argument string using the given--- function-expandMacros_ :: (MacroID->Maybe String) -> String -> String-expandMacros_ lu = fixpoint e_m- where- e_m re_s =- replaceAllCaptures TOP phi $ re_s *=~ [re|@$(@|\{${name}([^{}]+)\})|]-- phi mtch _ cap = case txt == "@@" of- True -> Just "@"- False -> Just $ fromMaybe txt $ lu ide- where- txt = capturedText cap- ide = MacroID $ capturedText $ capture [cp|name|] mtch--fixpoint :: (Eq a) => (a->a) -> a -> a-fixpoint f = chk . iterate f- where- chk (x:x':_) | x==x' = x- chk xs = chk $ tail xs+evalme_CLC_02 = checkThis "evalme_CLC_02" (False) $ ("quux" =~ [re|(foo|bar)|] :: Bool) \end{code}--For example: \begin{code}-evalme_PMC_00 = checkThis "evalme_PMC_00" ("foo MacroID {getMacroID = \"bar\"} baz") $ expandMacros_ (Just . show) "foo @{bar} baz"+evalme_CLC_03 = checkThis "evalme_CLC_03" (2) $ ("foobar" =~ [re|(foo|bar)|] :: Int) \end{code}--See [Text.RE.Replace](Replace.html) for details.---Example: Parsing Replace Templates-------------------------------------The regex replacement templates are parsed with code similar to this.- \begin{code}-type Template = String--parseTemplateR' :: Template- -> Match String- -> RELocation- -> Capture String- -> Maybe String-parseTemplateR' tpl mtch _ _ =- Just $ replaceAllCaptures TOP phi $- tpl *=~ [re|\$${arg}(\$|[0-9]+|\{${name}([^{}]+)\})|]- where- phi t_mtch _ _ = case t_mtch !$? [cp|name|] of- Just cap -> this $ IsCaptureName $ CaptureName txt- where- txt = T.pack $ capturedText cap- Nothing -> case t == "$" of- True -> Just t- False -> this $ IsCaptureOrdinal $ CaptureOrdinal $ read t- where- t = capturedText $ capture [cp|arg|] t_mtch-- this cid = capturedText <$> mtch !$? cid--my_replace :: RE -> Template-> String -> String-my_replace rex tpl src = replaceAllCaptures TOP (parseTemplateR' tpl) $ src *=~ rex+evalme_CLC_04 = checkThis "evalme_CLC_04" (Nothing) $ ("foo" =~~ [re|bar|] :: Maybe String) \end{code} -It can be tested with our date-reformater example.- \begin{code}-date_reformat :: String -> String-date_reformat = my_replace [re|${y}([0-9]{4})-${m}([0-9]{2})-${d}([0-9]{2})|] "${y}/${m}/${d}"-\end{code}--This should yield `"2016/01/11"`:--\begin{code}-evalme_TPL_00 = checkThis "evalme_TPL_00" ("2016/01/11") $ date_reformat "2016-01-11"-\end{code}--See [Text.RE.Replace](Replace.html)---Example: include preprocessor--------------------------------The 'include' preprocessor for extracting literate programming fragments-(used in this and most of the other sections of the tutorial) has been-lifted out of the main preprocessor into its own example.--Here is sed script that makes up the main loop.--%include "examples/re-include.lhs" "loop ::"--The `extract` action takes the path to the file containing the fragment-and the RE that will match a line in the fragment and returns the text-of the fragment (wrapped in a simple styling div).--%include "examples/re-include.lhs" "extract ::"--And here is the scanner for recognising the literate fragments.--%include "examples/re-include.lhs" "scan ::"--See [examples/re-include.lhs](re-include.html)---Example: literate preprocessor---------------------------------The preprocessor that converts this literate Haskell program into a web-page and a test suite that makes plenty of use of regex is in-[examples/re-prep.lhs](re-prep.html).---Example: gen-modules-----------------------The many TDFA and PCRE API modules (but _not_ the `RE` modules) are all-generated from `Text.RE.TDFA.ByteString.Lazy` with-[examples/re-gen-modules.lhs](re-gen-modules.html) which is also an-application of regex.---\begin{code} main :: IO () main = runTheTests- [ evalme_TPL_00- , evalme_PMC_00- , evalme_REU_01- , evalme_OPT_01- , evalme_OPT_00- , evalme_MAC_00- , evalme_RPF_02- , evalme_RPF_01+ [ evalme_CLC_04+ , evalme_CLC_03+ , evalme_CLC_02+ , evalme_CLC_01+ , evalme_CPL_03+ , evalme_CPL_02+ , evalme_CPL_01 , evalme_SOP_06 , evalme_SOP_05 , evalme_SOP_04 , evalme_SOP_03 , evalme_SOP_02 , evalme_SOP_01- , evalme_RPL_02- , evalme_RPL_01+ , evalme_SRP_01+ , evalme_SRP_00+ , evalme_MAC_01+ , evalme_MAC_00 , evalme_MLT_03 , evalme_MLT_02 , evalme_MLT_01+ , evalme_SGL_03 , evalme_SGL_02 , evalme_SGL_01- , evalme_TRD_04- , evalme_TRD_02- , evalme_TRD_01- , evalme_TRD_00- , evalme_LOA_00 ] \end{code}
lib/cabal-masters/executables-incl.cabal view
@@ -100,7 +100,7 @@ TestKit Default-Extensions: QuasiQuotes-%build-depends-prog regex array base base-compat bytestring containers directory hashable heredoc regex-base regex-tdfa regex-tdfa-text regex-pcre-builtin shelly smallcheck tasty tasty-hunit tasty-smallcheck template-haskell transformers text time time-locale-compat unordered-containers+%build-depends-prog regex regex-with-pcre array base base-compat bytestring containers directory hashable heredoc regex-base regex-tdfa regex-tdfa-text regex-pcre-builtin shelly smallcheck tasty tasty-hunit tasty-smallcheck template-haskell transformers text time time-locale-compat unordered-containers %test-exe re-tutorial-replacing Hs-Source-Dirs: examples
lib/cabal-masters/library-incl.cabal view
@@ -18,13 +18,17 @@ Text.RE.TDFA.Text Text.RE.TDFA.Text.Lazy Text.RE.TestBench+ Text.RE.TestBench.Parsers Text.RE.Tools Text.RE.Tools.Edit Text.RE.Tools.Find Text.RE.Tools.Grep+ Text.RE.Tools.IsRegex Text.RE.Tools.Lex Text.RE.Tools.Sed Text.RE.ZeInternals++ Other-Modules: Text.RE.ZeInternals.AddCaptureNames Text.RE.ZeInternals.EscapeREString Text.RE.ZeInternals.NamedCaptures@@ -58,5 +62,3 @@ Text.RE.ZeInternals.Types.Match Text.RE.ZeInternals.Types.Matches Text.RE.ZeInternals.Types.SearchReplace--%build-depends-lib array bytestring base base-compat containers hashable regex-base regex-tdfa regex-tdfa-text regex-pcre-builtin template-haskell text time time-locale-compat transformers unordered-containers
lib/cabal-masters/mega-regex.cabal view
@@ -38,6 +38,8 @@ %include "lib/cabal-masters/library-incl.cabal" +%build-depends-lib array bytestring base base-compat containers hashable regex-base regex-tdfa regex-tdfa-text regex-pcre-builtin template-haskell text time time-locale-compat transformers unordered-containers+ %include "lib/cabal-masters/executables-incl.cabal" -- Generated from lib/cabal-masters/mega-regex with re-gen-cabals
lib/cabal-masters/regex.cabal view
@@ -2,4 +2,7 @@ %include "lib/cabal-masters/regex-incl.cabal" %include "lib/cabal-masters/constraints-incl.cabal" %include "lib/cabal-masters/library-incl.cabal" exclude "PCRE"++%build-depends-lib array base base-compat bytestring containers hashable regex-base regex-tdfa regex-tdfa-text template-haskell text time time-locale-compat transformers unordered-containers+ -- Generated with re-gen-cabals
lib/cabal-masters/test-extra-source-files-incl.cabal view
@@ -31,3 +31,4 @@ src/Text/RE/TDFA/String.hs src/Text/RE/TDFA/Text.hs src/Text/RE/TDFA/Text/Lazy.hs+ stack-8.0.yaml
lib/mega-regex.cabal view
@@ -1,5 +1,5 @@ Name: regex-Version: 0.14.0.0+Version: 1.0.0.0 Synopsis: Toolkit for regex-base Description: A regular expression toolkit for regex-base with compile-time checking of RE syntax, data types for@@ -52,6 +52,7 @@ src/Text/RE/TDFA/String.hs src/Text/RE/TDFA/Text.hs src/Text/RE/TDFA/Text/Lazy.hs+ stack-8.0.yaml Cabal-Version: >= 1.10@@ -63,7 +64,7 @@ Source-Repository this Type: git Location: https://github.com/iconnect/regex.git- Tag: 0.14.0.0+ Tag: 1.0.0.0 @@ -87,13 +88,17 @@ Text.RE.TDFA.Text Text.RE.TDFA.Text.Lazy Text.RE.TestBench+ Text.RE.TestBench.Parsers Text.RE.Tools Text.RE.Tools.Edit Text.RE.Tools.Find Text.RE.Tools.Grep+ Text.RE.Tools.IsRegex Text.RE.Tools.Lex Text.RE.Tools.Sed Text.RE.ZeInternals++ Other-Modules: Text.RE.ZeInternals.AddCaptureNames Text.RE.ZeInternals.EscapeREString Text.RE.ZeInternals.NamedCaptures@@ -128,6 +133,7 @@ Text.RE.ZeInternals.Types.Matches Text.RE.ZeInternals.Types.SearchReplace + Default-Language: Haskell2010 Other-Extensions:@@ -179,7 +185,6 @@ , unordered-containers >= 0.2.5.1 - Executable re-gen-cabals Hs-Source-Dirs: examples @@ -196,7 +201,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -226,7 +231,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -256,7 +261,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -285,7 +290,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -314,7 +319,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -340,7 +345,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -366,7 +371,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -400,7 +405,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -434,7 +439,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -463,7 +468,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -492,7 +497,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -519,7 +524,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -546,7 +551,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -586,7 +591,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -627,7 +632,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -671,7 +676,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -717,7 +722,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -761,7 +766,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -805,7 +810,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -849,7 +854,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -893,7 +898,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -937,7 +942,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -981,7 +986,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -1025,7 +1030,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -1070,7 +1075,7 @@ -Werror Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0
lib/version.txt view
@@ -1,1 +1,1 @@-0.14.0.0+1.0.0.0
regex-examples.cabal view
@@ -1,5 +1,5 @@ Name: regex-examples-Version: 0.14.0.0+Version: 1.0.0.0 Synopsis: Tutorial, tests and example programs for regex Description: Tutorial, tests and example programs for regex, a Regular Expression Toolkit for regex-base with@@ -52,6 +52,7 @@ src/Text/RE/TDFA/String.hs src/Text/RE/TDFA/Text.hs src/Text/RE/TDFA/Text/Lazy.hs+ stack-8.0.yaml Cabal-Version: >= 1.10@@ -63,7 +64,7 @@ Source-Repository this Type: git Location: https://github.com/iconnect/regex.git- Tag: 0.14.0.0+ Tag: 1.0.0.0 Executable re-gen-cabals@@ -82,7 +83,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -112,7 +113,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -142,7 +143,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -171,7 +172,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -200,7 +201,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -226,7 +227,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -252,8 +253,8 @@ -Wwarn Build-depends:- regex == 0.14.0.0- , regex-with-pcre == 0.14.0.0+ regex == 1.0.0.0+ , regex-with-pcre == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -287,8 +288,8 @@ -Wwarn Build-depends:- regex == 0.14.0.0- , regex-with-pcre == 0.14.0.0+ regex == 1.0.0.0+ , regex-with-pcre == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -322,7 +323,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -351,7 +352,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -380,7 +381,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -407,7 +408,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , base >= 4 && < 5 , base-compat >= 0.6.0 , bytestring >= 0.10.2.0@@ -434,8 +435,8 @@ -Wwarn Build-depends:- regex == 0.14.0.0- , regex-with-pcre == 0.14.0.0+ regex == 1.0.0.0+ , regex-with-pcre == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -475,8 +476,8 @@ -Wwarn Build-depends:- regex == 0.14.0.0- , regex-with-pcre == 0.14.0.0+ regex == 1.0.0.0+ , regex-with-pcre == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -517,7 +518,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -561,7 +562,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -607,7 +608,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -651,7 +652,8 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0+ , regex-with-pcre == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -695,7 +697,8 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0+ , regex-with-pcre == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -739,7 +742,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -783,7 +786,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -827,7 +830,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -871,7 +874,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -915,7 +918,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0@@ -960,7 +963,7 @@ -Wwarn Build-depends:- regex == 0.14.0.0+ regex == 1.0.0.0 , array >= 0.4 , base >= 4 && < 5 , base-compat >= 0.6.0
src/Text/RE/PCRE/ByteString.hs view
@@ -20,18 +20,21 @@ -- * The 'SearchReplace' Operators , (*=~/) , (?=~/)- -- * Matches+ -- * The 'Matches' Type , Matches , matchesSource , allMatches , anyMatches , countMatches , matches- -- * Match+ -- * The 'Match' Type , Match , matchSource , matched , matchedText+ -- * The Macros and Parsers+ -- $macros+ , module Text.RE.TestBench.Parsers -- * The 'RE' Type , RE , reSource@@ -47,16 +50,38 @@ , escape , escapeWith , escapeREString- -- * The Classic rexex-base Match Operators+ -- * The Classic regex-base Match Operators , (=~) , (=~~)- -- * IsRegex- , IsRegex(..)- -- * The Quasi Quoters and Minor Functions+ -- * The re Quasi Quoters -- $re- , module Text.RE.ZeInternals.PCRE+ , re+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , reMS+ , reMI+ , reBS+ , reBI+ , re_+ -- * The Ed Quasi Quoters -- $ed- , module Text.RE.ZeInternals.SearchReplace.PCRE.ByteString+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed+ , edMS+ , edMI+ , edBS+ , edBI+ , ed_+ -- * The cp Quasi Quoters+ , cp+ -- * IsRegex+ -- $isregex+ , module Text.RE.Tools.IsRegex ) where import qualified Data.ByteString as B@@ -64,10 +89,11 @@ import Prelude.Compat import Text.RE.REOptions import Text.RE.Replace-import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.TestBench.Parsers+import Text.RE.Tools.IsRegex+import Text.RE.ZeInternals import Text.RE.ZeInternals.PCRE import Text.RE.ZeInternals.SearchReplace.PCRE.ByteString-import Text.RE.ZeInternals.Types.IsRegex import Text.Regex.Base import qualified Text.Regex.PCRE as PCRE @@ -102,7 +128,7 @@ (*=~/) = flip searchReplaceAll -- | search and replace the first occurrence only (if any) in the input text--- e.g., to prefix the first string of four hex digits in the imput text,+-- e.g., to prefix the first string of four hex digits in the input text, -- if any, with @0x@: -- -- @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@@@ -110,22 +136,20 @@ (?=~/) :: B.ByteString -> SearchReplace RE B.ByteString -> B.ByteString (?=~/) = flip searchReplaceFirst --- | the regex-base polymorphic match operator+-- | the `regex-base` polymorphic match operator (=~) :: ( Typeable a , RegexContext PCRE.Regex B.ByteString a- , RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String ) => B.ByteString -> RE -> a (=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs --- | the regex-base monadic, polymorphic match operator+-- | the `regex-base` monadic, polymorphic match operator (=~~) :: ( Monad m , Functor m , Typeable a , RegexContext PCRE.Regex B.ByteString a- , RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String ) => B.ByteString -> RE@@ -142,6 +166,11 @@ -- $tutorial -- We have a regex tutorial at <http://tutorial.regex.uk>. +-- $macros+-- There are a number of RE macros and corresponding Haskell parsers+-- for parsing the matched text into appropriate Haskell types. See+-- the [Macros Tables](http://regex.uk/macros) for details.+ -- $options -- You can specify different compilation options by appending a -- to the name of an [re| ... |] or [ed| ... \/\/\/ ... |] quasi quoter@@ -152,7 +181,7 @@ -- -- will replace a @foo@ suffix of the argument text, of any -- capitalisation, with a (lower case) @bar@. If you need to specify the--- options dynamically, use the @[re_| ... |]@ and @[red_| ... \/\/\/ ... |]@+-- options dynamically, use the @[re_| ... |]@ and @[ed_| ... \/\/\/ ... |]@ -- quasi quoters, which generate functions that take an 'IsOption' option -- (e.g., a 'SimpleReOptions' value) and yields a 'RE' or 'SearchReplace' -- as apropriate. For example if you have a 'SimpleReOptions' value in@@ -171,3 +200,18 @@ -- $ed -- The @[ed|.*\/\/\/foo|]@ quasi quoters, with variants for specifing different -- options to the RE compiler (see "Text.RE.REOptions").++-- $ed+-- The -- | the @[ed| ... \/\/\/ ... |]@ quasi quoters; for example,+--+-- @[ed|${y}([0-9]{4})-0*${m}([0-9]{2})-0*${d}([0-9]{2})\/\/\/${d}\/${m}\/${y}|])@+--+-- represents a @SearchReplace@ that will convert a YYYY-MM-DD format date+-- into a DD\/MM\/YYYY format date.+--+-- The only difference betweem these quasi quoters is the RE options that are set,+-- using the same conventions as the @[re| ... |]@ quasi quoters.++-- $isregex+-- The 'IsRegex' class is used to abstact over the different regex back ends and+-- the text types they work with -- see "Text.RE.Tools.IsRegex" for details.
src/Text/RE/PCRE/ByteString/Lazy.hs view
@@ -20,18 +20,21 @@ -- * The 'SearchReplace' Operators , (*=~/) , (?=~/)- -- * Matches+ -- * The 'Matches' Type , Matches , matchesSource , allMatches , anyMatches , countMatches , matches- -- * Match+ -- * The 'Match' Type , Match , matchSource , matched , matchedText+ -- * The Macros and Parsers+ -- $macros+ , module Text.RE.TestBench.Parsers -- * The 'RE' Type , RE , reSource@@ -47,16 +50,38 @@ , escape , escapeWith , escapeREString- -- * The Classic rexex-base Match Operators+ -- * The Classic regex-base Match Operators , (=~) , (=~~)- -- * IsRegex- , IsRegex(..)- -- * The Quasi Quoters and Minor Functions+ -- * The re Quasi Quoters -- $re- , module Text.RE.ZeInternals.PCRE+ , re+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , reMS+ , reMI+ , reBS+ , reBI+ , re_+ -- * The Ed Quasi Quoters -- $ed- , module Text.RE.ZeInternals.SearchReplace.PCRE.ByteString.Lazy+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed+ , edMS+ , edMI+ , edBS+ , edBI+ , ed_+ -- * The cp Quasi Quoters+ , cp+ -- * IsRegex+ -- $isregex+ , module Text.RE.Tools.IsRegex ) where import qualified Data.ByteString.Lazy as LBS@@ -64,10 +89,11 @@ import Prelude.Compat import Text.RE.REOptions import Text.RE.Replace-import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.TestBench.Parsers+import Text.RE.Tools.IsRegex+import Text.RE.ZeInternals import Text.RE.ZeInternals.PCRE import Text.RE.ZeInternals.SearchReplace.PCRE.ByteString.Lazy-import Text.RE.ZeInternals.Types.IsRegex import Text.Regex.Base import qualified Text.Regex.PCRE as PCRE @@ -102,7 +128,7 @@ (*=~/) = flip searchReplaceAll -- | search and replace the first occurrence only (if any) in the input text--- e.g., to prefix the first string of four hex digits in the imput text,+-- e.g., to prefix the first string of four hex digits in the input text, -- if any, with @0x@: -- -- @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@@@ -110,22 +136,20 @@ (?=~/) :: LBS.ByteString -> SearchReplace RE LBS.ByteString -> LBS.ByteString (?=~/) = flip searchReplaceFirst --- | the regex-base polymorphic match operator+-- | the `regex-base` polymorphic match operator (=~) :: ( Typeable a , RegexContext PCRE.Regex LBS.ByteString a- , RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String ) => LBS.ByteString -> RE -> a (=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs --- | the regex-base monadic, polymorphic match operator+-- | the `regex-base` monadic, polymorphic match operator (=~~) :: ( Monad m , Functor m , Typeable a , RegexContext PCRE.Regex LBS.ByteString a- , RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String ) => LBS.ByteString -> RE@@ -142,6 +166,11 @@ -- $tutorial -- We have a regex tutorial at <http://tutorial.regex.uk>. +-- $macros+-- There are a number of RE macros and corresponding Haskell parsers+-- for parsing the matched text into appropriate Haskell types. See+-- the [Macros Tables](http://regex.uk/macros) for details.+ -- $options -- You can specify different compilation options by appending a -- to the name of an [re| ... |] or [ed| ... \/\/\/ ... |] quasi quoter@@ -152,7 +181,7 @@ -- -- will replace a @foo@ suffix of the argument text, of any -- capitalisation, with a (lower case) @bar@. If you need to specify the--- options dynamically, use the @[re_| ... |]@ and @[red_| ... \/\/\/ ... |]@+-- options dynamically, use the @[re_| ... |]@ and @[ed_| ... \/\/\/ ... |]@ -- quasi quoters, which generate functions that take an 'IsOption' option -- (e.g., a 'SimpleReOptions' value) and yields a 'RE' or 'SearchReplace' -- as apropriate. For example if you have a 'SimpleReOptions' value in@@ -171,3 +200,18 @@ -- $ed -- The @[ed|.*\/\/\/foo|]@ quasi quoters, with variants for specifing different -- options to the RE compiler (see "Text.RE.REOptions").++-- $ed+-- The -- | the @[ed| ... \/\/\/ ... |]@ quasi quoters; for example,+--+-- @[ed|${y}([0-9]{4})-0*${m}([0-9]{2})-0*${d}([0-9]{2})\/\/\/${d}\/${m}\/${y}|])@+--+-- represents a @SearchReplace@ that will convert a YYYY-MM-DD format date+-- into a DD\/MM\/YYYY format date.+--+-- The only difference betweem these quasi quoters is the RE options that are set,+-- using the same conventions as the @[re| ... |]@ quasi quoters.++-- $isregex+-- The 'IsRegex' class is used to abstact over the different regex back ends and+-- the text types they work with -- see "Text.RE.Tools.IsRegex" for details.
src/Text/RE/PCRE/Sequence.hs view
@@ -20,18 +20,21 @@ -- * The 'SearchReplace' Operators , (*=~/) , (?=~/)- -- * Matches+ -- * The 'Matches' Type , Matches , matchesSource , allMatches , anyMatches , countMatches , matches- -- * Match+ -- * The 'Match' Type , Match , matchSource , matched , matchedText+ -- * The Macros and Parsers+ -- $macros+ , module Text.RE.TestBench.Parsers -- * The 'RE' Type , RE , reSource@@ -47,16 +50,38 @@ , escape , escapeWith , escapeREString- -- * The Classic rexex-base Match Operators+ -- * The Classic regex-base Match Operators , (=~) , (=~~)- -- * IsRegex- , IsRegex(..)- -- * The Quasi Quoters and Minor Functions+ -- * The re Quasi Quoters -- $re- , module Text.RE.ZeInternals.PCRE+ , re+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , reMS+ , reMI+ , reBS+ , reBI+ , re_+ -- * The Ed Quasi Quoters -- $ed- , module Text.RE.ZeInternals.SearchReplace.PCRE.Sequence+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed+ , edMS+ , edMI+ , edBS+ , edBI+ , ed_+ -- * The cp Quasi Quoters+ , cp+ -- * IsRegex+ -- $isregex+ , module Text.RE.Tools.IsRegex ) where import qualified Data.Sequence as S@@ -64,10 +89,11 @@ import Prelude.Compat import Text.RE.REOptions import Text.RE.Replace-import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.TestBench.Parsers+import Text.RE.Tools.IsRegex+import Text.RE.ZeInternals import Text.RE.ZeInternals.PCRE import Text.RE.ZeInternals.SearchReplace.PCRE.Sequence-import Text.RE.ZeInternals.Types.IsRegex import Text.Regex.Base import qualified Text.Regex.PCRE as PCRE @@ -102,7 +128,7 @@ (*=~/) = flip searchReplaceAll -- | search and replace the first occurrence only (if any) in the input text--- e.g., to prefix the first string of four hex digits in the imput text,+-- e.g., to prefix the first string of four hex digits in the input text, -- if any, with @0x@: -- -- @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@@@ -110,22 +136,20 @@ (?=~/) :: (S.Seq Char) -> SearchReplace RE (S.Seq Char) -> (S.Seq Char) (?=~/) = flip searchReplaceFirst --- | the regex-base polymorphic match operator+-- | the `regex-base` polymorphic match operator (=~) :: ( Typeable a , RegexContext PCRE.Regex (S.Seq Char) a- , RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String ) => (S.Seq Char) -> RE -> a (=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs --- | the regex-base monadic, polymorphic match operator+-- | the `regex-base` monadic, polymorphic match operator (=~~) :: ( Monad m , Functor m , Typeable a , RegexContext PCRE.Regex (S.Seq Char) a- , RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String ) => (S.Seq Char) -> RE@@ -142,6 +166,11 @@ -- $tutorial -- We have a regex tutorial at <http://tutorial.regex.uk>. +-- $macros+-- There are a number of RE macros and corresponding Haskell parsers+-- for parsing the matched text into appropriate Haskell types. See+-- the [Macros Tables](http://regex.uk/macros) for details.+ -- $options -- You can specify different compilation options by appending a -- to the name of an [re| ... |] or [ed| ... \/\/\/ ... |] quasi quoter@@ -152,7 +181,7 @@ -- -- will replace a @foo@ suffix of the argument text, of any -- capitalisation, with a (lower case) @bar@. If you need to specify the--- options dynamically, use the @[re_| ... |]@ and @[red_| ... \/\/\/ ... |]@+-- options dynamically, use the @[re_| ... |]@ and @[ed_| ... \/\/\/ ... |]@ -- quasi quoters, which generate functions that take an 'IsOption' option -- (e.g., a 'SimpleReOptions' value) and yields a 'RE' or 'SearchReplace' -- as apropriate. For example if you have a 'SimpleReOptions' value in@@ -171,3 +200,18 @@ -- $ed -- The @[ed|.*\/\/\/foo|]@ quasi quoters, with variants for specifing different -- options to the RE compiler (see "Text.RE.REOptions").++-- $ed+-- The -- | the @[ed| ... \/\/\/ ... |]@ quasi quoters; for example,+--+-- @[ed|${y}([0-9]{4})-0*${m}([0-9]{2})-0*${d}([0-9]{2})\/\/\/${d}\/${m}\/${y}|])@+--+-- represents a @SearchReplace@ that will convert a YYYY-MM-DD format date+-- into a DD\/MM\/YYYY format date.+--+-- The only difference betweem these quasi quoters is the RE options that are set,+-- using the same conventions as the @[re| ... |]@ quasi quoters.++-- $isregex+-- The 'IsRegex' class is used to abstact over the different regex back ends and+-- the text types they work with -- see "Text.RE.Tools.IsRegex" for details.
src/Text/RE/PCRE/String.hs view
@@ -20,18 +20,21 @@ -- * The 'SearchReplace' Operators , (*=~/) , (?=~/)- -- * Matches+ -- * The 'Matches' Type , Matches , matchesSource , allMatches , anyMatches , countMatches , matches- -- * Match+ -- * The 'Match' Type , Match , matchSource , matched , matchedText+ -- * The Macros and Parsers+ -- $macros+ , module Text.RE.TestBench.Parsers -- * The 'RE' Type , RE , reSource@@ -47,16 +50,38 @@ , escape , escapeWith , escapeREString- -- * The Classic rexex-base Match Operators+ -- * The Classic regex-base Match Operators , (=~) , (=~~)- -- * IsRegex- , IsRegex(..)- -- * The Quasi Quoters and Minor Functions+ -- * The re Quasi Quoters -- $re- , module Text.RE.ZeInternals.PCRE+ , re+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , reMS+ , reMI+ , reBS+ , reBI+ , re_+ -- * The Ed Quasi Quoters -- $ed- , module Text.RE.ZeInternals.SearchReplace.PCRE.String+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed+ , edMS+ , edMI+ , edBS+ , edBI+ , ed_+ -- * The cp Quasi Quoters+ , cp+ -- * IsRegex+ -- $isregex+ , module Text.RE.Tools.IsRegex ) where @@ -64,10 +89,11 @@ import Prelude.Compat import Text.RE.REOptions import Text.RE.Replace-import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.TestBench.Parsers+import Text.RE.Tools.IsRegex+import Text.RE.ZeInternals import Text.RE.ZeInternals.PCRE import Text.RE.ZeInternals.SearchReplace.PCRE.String-import Text.RE.ZeInternals.Types.IsRegex import Text.Regex.Base import qualified Text.Regex.PCRE as PCRE @@ -102,7 +128,7 @@ (*=~/) = flip searchReplaceAll -- | search and replace the first occurrence only (if any) in the input text--- e.g., to prefix the first string of four hex digits in the imput text,+-- e.g., to prefix the first string of four hex digits in the input text, -- if any, with @0x@: -- -- @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@@@ -110,22 +136,20 @@ (?=~/) :: String -> SearchReplace RE String -> String (?=~/) = flip searchReplaceFirst --- | the regex-base polymorphic match operator+-- | the `regex-base` polymorphic match operator (=~) :: ( Typeable a , RegexContext PCRE.Regex String a- , RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String ) => String -> RE -> a (=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs --- | the regex-base monadic, polymorphic match operator+-- | the `regex-base` monadic, polymorphic match operator (=~~) :: ( Monad m , Functor m , Typeable a , RegexContext PCRE.Regex String a- , RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String ) => String -> RE@@ -142,6 +166,11 @@ -- $tutorial -- We have a regex tutorial at <http://tutorial.regex.uk>. +-- $macros+-- There are a number of RE macros and corresponding Haskell parsers+-- for parsing the matched text into appropriate Haskell types. See+-- the [Macros Tables](http://regex.uk/macros) for details.+ -- $options -- You can specify different compilation options by appending a -- to the name of an [re| ... |] or [ed| ... \/\/\/ ... |] quasi quoter@@ -152,7 +181,7 @@ -- -- will replace a @foo@ suffix of the argument text, of any -- capitalisation, with a (lower case) @bar@. If you need to specify the--- options dynamically, use the @[re_| ... |]@ and @[red_| ... \/\/\/ ... |]@+-- options dynamically, use the @[re_| ... |]@ and @[ed_| ... \/\/\/ ... |]@ -- quasi quoters, which generate functions that take an 'IsOption' option -- (e.g., a 'SimpleReOptions' value) and yields a 'RE' or 'SearchReplace' -- as apropriate. For example if you have a 'SimpleReOptions' value in@@ -171,3 +200,18 @@ -- $ed -- The @[ed|.*\/\/\/foo|]@ quasi quoters, with variants for specifing different -- options to the RE compiler (see "Text.RE.REOptions").++-- $ed+-- The -- | the @[ed| ... \/\/\/ ... |]@ quasi quoters; for example,+--+-- @[ed|${y}([0-9]{4})-0*${m}([0-9]{2})-0*${d}([0-9]{2})\/\/\/${d}\/${m}\/${y}|])@+--+-- represents a @SearchReplace@ that will convert a YYYY-MM-DD format date+-- into a DD\/MM\/YYYY format date.+--+-- The only difference betweem these quasi quoters is the RE options that are set,+-- using the same conventions as the @[re| ... |]@ quasi quoters.++-- $isregex+-- The 'IsRegex' class is used to abstact over the different regex back ends and+-- the text types they work with -- see "Text.RE.Tools.IsRegex" for details.
src/Text/RE/TDFA/ByteString.hs view
@@ -20,18 +20,21 @@ -- * The 'SearchReplace' Operators , (*=~/) , (?=~/)- -- * Matches+ -- * The 'Matches' Type , Matches , matchesSource , allMatches , anyMatches , countMatches , matches- -- * Match+ -- * The 'Match' Type , Match , matchSource , matched , matchedText+ -- * The Macros and Parsers+ -- $macros+ , module Text.RE.TestBench.Parsers -- * The 'RE' Type , RE , reSource@@ -47,16 +50,38 @@ , escape , escapeWith , escapeREString- -- * The Classic rexex-base Match Operators+ -- * The Classic regex-base Match Operators , (=~) , (=~~)- -- * IsRegex- , IsRegex(..)- -- * The Quasi Quoters and Minor Functions+ -- * The re Quasi Quoters -- $re- , module Text.RE.ZeInternals.TDFA+ , re+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , reMS+ , reMI+ , reBS+ , reBI+ , re_+ -- * The Ed Quasi Quoters -- $ed- , module Text.RE.ZeInternals.SearchReplace.TDFA.ByteString+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed+ , edMS+ , edMI+ , edBS+ , edBI+ , ed_+ -- * The cp Quasi Quoters+ , cp+ -- * IsRegex+ -- $isregex+ , module Text.RE.Tools.IsRegex ) where import qualified Data.ByteString as B@@ -64,10 +89,11 @@ import Prelude.Compat import Text.RE.REOptions import Text.RE.Replace-import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.TestBench.Parsers+import Text.RE.Tools.IsRegex+import Text.RE.ZeInternals import Text.RE.ZeInternals.SearchReplace.TDFA.ByteString import Text.RE.ZeInternals.TDFA-import Text.RE.ZeInternals.Types.IsRegex import Text.Regex.Base import qualified Text.Regex.TDFA as TDFA @@ -102,7 +128,7 @@ (*=~/) = flip searchReplaceAll -- | search and replace the first occurrence only (if any) in the input text--- e.g., to prefix the first string of four hex digits in the imput text,+-- e.g., to prefix the first string of four hex digits in the input text, -- if any, with @0x@: -- -- @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@@@ -110,22 +136,20 @@ (?=~/) :: B.ByteString -> SearchReplace RE B.ByteString -> B.ByteString (?=~/) = flip searchReplaceFirst --- | the regex-base polymorphic match operator+-- | the `regex-base` polymorphic match operator (=~) :: ( Typeable a , RegexContext TDFA.Regex B.ByteString a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => B.ByteString -> RE -> a (=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs --- | the regex-base monadic, polymorphic match operator+-- | the `regex-base` monadic, polymorphic match operator (=~~) :: ( Monad m , Functor m , Typeable a , RegexContext TDFA.Regex B.ByteString a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => B.ByteString -> RE@@ -142,6 +166,11 @@ -- $tutorial -- We have a regex tutorial at <http://tutorial.regex.uk>. +-- $macros+-- There are a number of RE macros and corresponding Haskell parsers+-- for parsing the matched text into appropriate Haskell types. See+-- the [Macros Tables](http://regex.uk/macros) for details.+ -- $options -- You can specify different compilation options by appending a -- to the name of an [re| ... |] or [ed| ... \/\/\/ ... |] quasi quoter@@ -152,7 +181,7 @@ -- -- will replace a @foo@ suffix of the argument text, of any -- capitalisation, with a (lower case) @bar@. If you need to specify the--- options dynamically, use the @[re_| ... |]@ and @[red_| ... \/\/\/ ... |]@+-- options dynamically, use the @[re_| ... |]@ and @[ed_| ... \/\/\/ ... |]@ -- quasi quoters, which generate functions that take an 'IsOption' option -- (e.g., a 'SimpleReOptions' value) and yields a 'RE' or 'SearchReplace' -- as apropriate. For example if you have a 'SimpleReOptions' value in@@ -171,3 +200,18 @@ -- $ed -- The @[ed|.*\/\/\/foo|]@ quasi quoters, with variants for specifing different -- options to the RE compiler (see "Text.RE.REOptions").++-- $ed+-- The -- | the @[ed| ... \/\/\/ ... |]@ quasi quoters; for example,+--+-- @[ed|${y}([0-9]{4})-0*${m}([0-9]{2})-0*${d}([0-9]{2})\/\/\/${d}\/${m}\/${y}|])@+--+-- represents a @SearchReplace@ that will convert a YYYY-MM-DD format date+-- into a DD\/MM\/YYYY format date.+--+-- The only difference betweem these quasi quoters is the RE options that are set,+-- using the same conventions as the @[re| ... |]@ quasi quoters.++-- $isregex+-- The 'IsRegex' class is used to abstact over the different regex back ends and+-- the text types they work with -- see "Text.RE.Tools.IsRegex" for details.
src/Text/RE/TDFA/ByteString/Lazy.hs view
@@ -20,18 +20,21 @@ -- * The 'SearchReplace' Operators , (*=~/) , (?=~/)- -- * Matches+ -- * The 'Matches' Type , Matches , matchesSource , allMatches , anyMatches , countMatches , matches- -- * Match+ -- * The 'Match' Type , Match , matchSource , matched , matchedText+ -- * The Macros and Parsers+ -- $macros+ , module Text.RE.TestBench.Parsers -- * The 'RE' Type , RE , reSource@@ -47,16 +50,38 @@ , escape , escapeWith , escapeREString- -- * The Classic rexex-base Match Operators+ -- * The Classic regex-base Match Operators , (=~) , (=~~)- -- * IsRegex- , IsRegex(..)- -- * The Quasi Quoters and Minor Functions+ -- * The re Quasi Quoters -- $re- , module Text.RE.ZeInternals.TDFA+ , re+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , reMS+ , reMI+ , reBS+ , reBI+ , re_+ -- * The Ed Quasi Quoters -- $ed- , module Text.RE.ZeInternals.SearchReplace.TDFA.ByteString.Lazy+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed+ , edMS+ , edMI+ , edBS+ , edBI+ , ed_+ -- * The cp Quasi Quoters+ , cp+ -- * IsRegex+ -- $isregex+ , module Text.RE.Tools.IsRegex ) where import qualified Data.ByteString.Lazy.Char8 as LBS@@ -64,10 +89,11 @@ import Prelude.Compat import Text.RE.REOptions import Text.RE.Replace-import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.TestBench.Parsers+import Text.RE.Tools.IsRegex+import Text.RE.ZeInternals import Text.RE.ZeInternals.SearchReplace.TDFA.ByteString.Lazy import Text.RE.ZeInternals.TDFA-import Text.RE.ZeInternals.Types.IsRegex import Text.Regex.Base import qualified Text.Regex.TDFA as TDFA @@ -102,7 +128,7 @@ (*=~/) = flip searchReplaceAll -- | search and replace the first occurrence only (if any) in the input text--- e.g., to prefix the first string of four hex digits in the imput text,+-- e.g., to prefix the first string of four hex digits in the input text, -- if any, with @0x@: -- -- @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@@@ -110,22 +136,20 @@ (?=~/) :: LBS.ByteString -> SearchReplace RE LBS.ByteString -> LBS.ByteString (?=~/) = flip searchReplaceFirst --- | the regex-base polymorphic match operator+-- | the `regex-base` polymorphic match operator (=~) :: ( Typeable a , RegexContext TDFA.Regex LBS.ByteString a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => LBS.ByteString -> RE -> a (=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs --- | the regex-base monadic, polymorphic match operator+-- | the `regex-base` monadic, polymorphic match operator (=~~) :: ( Monad m , Functor m , Typeable a , RegexContext TDFA.Regex LBS.ByteString a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => LBS.ByteString -> RE@@ -142,6 +166,11 @@ -- $tutorial -- We have a regex tutorial at <http://tutorial.regex.uk>. +-- $macros+-- There are a number of RE macros and corresponding Haskell parsers+-- for parsing the matched text into appropriate Haskell types. See+-- the [Macros Tables](http://regex.uk/macros) for details.+ -- $options -- You can specify different compilation options by appending a -- to the name of an [re| ... |] or [ed| ... \/\/\/ ... |] quasi quoter@@ -152,7 +181,7 @@ -- -- will replace a @foo@ suffix of the argument text, of any -- capitalisation, with a (lower case) @bar@. If you need to specify the--- options dynamically, use the @[re_| ... |]@ and @[red_| ... \/\/\/ ... |]@+-- options dynamically, use the @[re_| ... |]@ and @[ed_| ... \/\/\/ ... |]@ -- quasi quoters, which generate functions that take an 'IsOption' option -- (e.g., a 'SimpleReOptions' value) and yields a 'RE' or 'SearchReplace' -- as apropriate. For example if you have a 'SimpleReOptions' value in@@ -171,3 +200,18 @@ -- $ed -- The @[ed|.*\/\/\/foo|]@ quasi quoters, with variants for specifing different -- options to the RE compiler (see "Text.RE.REOptions").++-- $ed+-- The -- | the @[ed| ... \/\/\/ ... |]@ quasi quoters; for example,+--+-- @[ed|${y}([0-9]{4})-0*${m}([0-9]{2})-0*${d}([0-9]{2})\/\/\/${d}\/${m}\/${y}|])@+--+-- represents a @SearchReplace@ that will convert a YYYY-MM-DD format date+-- into a DD\/MM\/YYYY format date.+--+-- The only difference betweem these quasi quoters is the RE options that are set,+-- using the same conventions as the @[re| ... |]@ quasi quoters.++-- $isregex+-- The 'IsRegex' class is used to abstact over the different regex back ends and+-- the text types they work with -- see "Text.RE.Tools.IsRegex" for details.
src/Text/RE/TDFA/Sequence.hs view
@@ -20,18 +20,21 @@ -- * The 'SearchReplace' Operators , (*=~/) , (?=~/)- -- * Matches+ -- * The 'Matches' Type , Matches , matchesSource , allMatches , anyMatches , countMatches , matches- -- * Match+ -- * The 'Match' Type , Match , matchSource , matched , matchedText+ -- * The Macros and Parsers+ -- $macros+ , module Text.RE.TestBench.Parsers -- * The 'RE' Type , RE , reSource@@ -47,16 +50,38 @@ , escape , escapeWith , escapeREString- -- * The Classic rexex-base Match Operators+ -- * The Classic regex-base Match Operators , (=~) , (=~~)- -- * IsRegex- , IsRegex(..)- -- * The Quasi Quoters and Minor Functions+ -- * The re Quasi Quoters -- $re- , module Text.RE.ZeInternals.TDFA+ , re+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , reMS+ , reMI+ , reBS+ , reBI+ , re_+ -- * The Ed Quasi Quoters -- $ed- , module Text.RE.ZeInternals.SearchReplace.TDFA.Sequence+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed+ , edMS+ , edMI+ , edBS+ , edBI+ , ed_+ -- * The cp Quasi Quoters+ , cp+ -- * IsRegex+ -- $isregex+ , module Text.RE.Tools.IsRegex ) where import qualified Data.Sequence as S@@ -64,10 +89,11 @@ import Prelude.Compat import Text.RE.REOptions import Text.RE.Replace-import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.TestBench.Parsers+import Text.RE.Tools.IsRegex+import Text.RE.ZeInternals import Text.RE.ZeInternals.SearchReplace.TDFA.Sequence import Text.RE.ZeInternals.TDFA-import Text.RE.ZeInternals.Types.IsRegex import Text.Regex.Base import qualified Text.Regex.TDFA as TDFA @@ -102,7 +128,7 @@ (*=~/) = flip searchReplaceAll -- | search and replace the first occurrence only (if any) in the input text--- e.g., to prefix the first string of four hex digits in the imput text,+-- e.g., to prefix the first string of four hex digits in the input text, -- if any, with @0x@: -- -- @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@@@ -110,22 +136,20 @@ (?=~/) :: (S.Seq Char) -> SearchReplace RE (S.Seq Char) -> (S.Seq Char) (?=~/) = flip searchReplaceFirst --- | the regex-base polymorphic match operator+-- | the `regex-base` polymorphic match operator (=~) :: ( Typeable a , RegexContext TDFA.Regex (S.Seq Char) a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => (S.Seq Char) -> RE -> a (=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs --- | the regex-base monadic, polymorphic match operator+-- | the `regex-base` monadic, polymorphic match operator (=~~) :: ( Monad m , Functor m , Typeable a , RegexContext TDFA.Regex (S.Seq Char) a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => (S.Seq Char) -> RE@@ -142,6 +166,11 @@ -- $tutorial -- We have a regex tutorial at <http://tutorial.regex.uk>. +-- $macros+-- There are a number of RE macros and corresponding Haskell parsers+-- for parsing the matched text into appropriate Haskell types. See+-- the [Macros Tables](http://regex.uk/macros) for details.+ -- $options -- You can specify different compilation options by appending a -- to the name of an [re| ... |] or [ed| ... \/\/\/ ... |] quasi quoter@@ -152,7 +181,7 @@ -- -- will replace a @foo@ suffix of the argument text, of any -- capitalisation, with a (lower case) @bar@. If you need to specify the--- options dynamically, use the @[re_| ... |]@ and @[red_| ... \/\/\/ ... |]@+-- options dynamically, use the @[re_| ... |]@ and @[ed_| ... \/\/\/ ... |]@ -- quasi quoters, which generate functions that take an 'IsOption' option -- (e.g., a 'SimpleReOptions' value) and yields a 'RE' or 'SearchReplace' -- as apropriate. For example if you have a 'SimpleReOptions' value in@@ -171,3 +200,18 @@ -- $ed -- The @[ed|.*\/\/\/foo|]@ quasi quoters, with variants for specifing different -- options to the RE compiler (see "Text.RE.REOptions").++-- $ed+-- The -- | the @[ed| ... \/\/\/ ... |]@ quasi quoters; for example,+--+-- @[ed|${y}([0-9]{4})-0*${m}([0-9]{2})-0*${d}([0-9]{2})\/\/\/${d}\/${m}\/${y}|])@+--+-- represents a @SearchReplace@ that will convert a YYYY-MM-DD format date+-- into a DD\/MM\/YYYY format date.+--+-- The only difference betweem these quasi quoters is the RE options that are set,+-- using the same conventions as the @[re| ... |]@ quasi quoters.++-- $isregex+-- The 'IsRegex' class is used to abstact over the different regex back ends and+-- the text types they work with -- see "Text.RE.Tools.IsRegex" for details.
src/Text/RE/TDFA/String.hs view
@@ -20,18 +20,21 @@ -- * The 'SearchReplace' Operators , (*=~/) , (?=~/)- -- * Matches+ -- * The 'Matches' Type , Matches , matchesSource , allMatches , anyMatches , countMatches , matches- -- * Match+ -- * The 'Match' Type , Match , matchSource , matched , matchedText+ -- * The Macros and Parsers+ -- $macros+ , module Text.RE.TestBench.Parsers -- * The 'RE' Type , RE , reSource@@ -47,16 +50,38 @@ , escape , escapeWith , escapeREString- -- * The Classic rexex-base Match Operators+ -- * The Classic regex-base Match Operators , (=~) , (=~~)- -- * IsRegex- , IsRegex(..)- -- * The Quasi Quoters and Minor Functions+ -- * The re Quasi Quoters -- $re- , module Text.RE.ZeInternals.TDFA+ , re+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , reMS+ , reMI+ , reBS+ , reBI+ , re_+ -- * The Ed Quasi Quoters -- $ed- , module Text.RE.ZeInternals.SearchReplace.TDFA.String+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed+ , edMS+ , edMI+ , edBS+ , edBI+ , ed_+ -- * The cp Quasi Quoters+ , cp+ -- * IsRegex+ -- $isregex+ , module Text.RE.Tools.IsRegex ) where @@ -64,10 +89,11 @@ import Prelude.Compat import Text.RE.REOptions import Text.RE.Replace-import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.TestBench.Parsers+import Text.RE.Tools.IsRegex+import Text.RE.ZeInternals import Text.RE.ZeInternals.SearchReplace.TDFA.String import Text.RE.ZeInternals.TDFA-import Text.RE.ZeInternals.Types.IsRegex import Text.Regex.Base import qualified Text.Regex.TDFA as TDFA @@ -102,7 +128,7 @@ (*=~/) = flip searchReplaceAll -- | search and replace the first occurrence only (if any) in the input text--- e.g., to prefix the first string of four hex digits in the imput text,+-- e.g., to prefix the first string of four hex digits in the input text, -- if any, with @0x@: -- -- @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@@@ -110,22 +136,20 @@ (?=~/) :: String -> SearchReplace RE String -> String (?=~/) = flip searchReplaceFirst --- | the regex-base polymorphic match operator+-- | the `regex-base` polymorphic match operator (=~) :: ( Typeable a , RegexContext TDFA.Regex String a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => String -> RE -> a (=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs --- | the regex-base monadic, polymorphic match operator+-- | the `regex-base` monadic, polymorphic match operator (=~~) :: ( Monad m , Functor m , Typeable a , RegexContext TDFA.Regex String a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => String -> RE@@ -142,6 +166,11 @@ -- $tutorial -- We have a regex tutorial at <http://tutorial.regex.uk>. +-- $macros+-- There are a number of RE macros and corresponding Haskell parsers+-- for parsing the matched text into appropriate Haskell types. See+-- the [Macros Tables](http://regex.uk/macros) for details.+ -- $options -- You can specify different compilation options by appending a -- to the name of an [re| ... |] or [ed| ... \/\/\/ ... |] quasi quoter@@ -152,7 +181,7 @@ -- -- will replace a @foo@ suffix of the argument text, of any -- capitalisation, with a (lower case) @bar@. If you need to specify the--- options dynamically, use the @[re_| ... |]@ and @[red_| ... \/\/\/ ... |]@+-- options dynamically, use the @[re_| ... |]@ and @[ed_| ... \/\/\/ ... |]@ -- quasi quoters, which generate functions that take an 'IsOption' option -- (e.g., a 'SimpleReOptions' value) and yields a 'RE' or 'SearchReplace' -- as apropriate. For example if you have a 'SimpleReOptions' value in@@ -171,3 +200,18 @@ -- $ed -- The @[ed|.*\/\/\/foo|]@ quasi quoters, with variants for specifing different -- options to the RE compiler (see "Text.RE.REOptions").++-- $ed+-- The -- | the @[ed| ... \/\/\/ ... |]@ quasi quoters; for example,+--+-- @[ed|${y}([0-9]{4})-0*${m}([0-9]{2})-0*${d}([0-9]{2})\/\/\/${d}\/${m}\/${y}|])@+--+-- represents a @SearchReplace@ that will convert a YYYY-MM-DD format date+-- into a DD\/MM\/YYYY format date.+--+-- The only difference betweem these quasi quoters is the RE options that are set,+-- using the same conventions as the @[re| ... |]@ quasi quoters.++-- $isregex+-- The 'IsRegex' class is used to abstact over the different regex back ends and+-- the text types they work with -- see "Text.RE.Tools.IsRegex" for details.
src/Text/RE/TDFA/Text.hs view
@@ -20,18 +20,21 @@ -- * The 'SearchReplace' Operators , (*=~/) , (?=~/)- -- * Matches+ -- * The 'Matches' Type , Matches , matchesSource , allMatches , anyMatches , countMatches , matches- -- * Match+ -- * The 'Match' Type , Match , matchSource , matched , matchedText+ -- * The Macros and Parsers+ -- $macros+ , module Text.RE.TestBench.Parsers -- * The 'RE' Type , RE , reSource@@ -47,16 +50,38 @@ , escape , escapeWith , escapeREString- -- * The Classic rexex-base Match Operators+ -- * The Classic regex-base Match Operators , (=~) , (=~~)- -- * IsRegex- , IsRegex(..)- -- * The Quasi Quoters and Minor Functions+ -- * The re Quasi Quoters -- $re- , module Text.RE.ZeInternals.TDFA+ , re+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , reMS+ , reMI+ , reBS+ , reBI+ , re_+ -- * The Ed Quasi Quoters -- $ed- , module Text.RE.ZeInternals.SearchReplace.TDFA.Text+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed+ , edMS+ , edMI+ , edBS+ , edBI+ , ed_+ -- * The cp Quasi Quoters+ , cp+ -- * IsRegex+ -- $isregex+ , module Text.RE.Tools.IsRegex ) where import qualified Data.Text as T@@ -64,10 +89,11 @@ import Prelude.Compat import Text.RE.REOptions import Text.RE.Replace-import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.TestBench.Parsers+import Text.RE.Tools.IsRegex+import Text.RE.ZeInternals import Text.RE.ZeInternals.SearchReplace.TDFA.Text import Text.RE.ZeInternals.TDFA-import Text.RE.ZeInternals.Types.IsRegex import Text.Regex.Base import qualified Text.Regex.TDFA as TDFA @@ -102,7 +128,7 @@ (*=~/) = flip searchReplaceAll -- | search and replace the first occurrence only (if any) in the input text--- e.g., to prefix the first string of four hex digits in the imput text,+-- e.g., to prefix the first string of four hex digits in the input text, -- if any, with @0x@: -- -- @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@@@ -110,22 +136,20 @@ (?=~/) :: T.Text -> SearchReplace RE T.Text -> T.Text (?=~/) = flip searchReplaceFirst --- | the regex-base polymorphic match operator+-- | the `regex-base` polymorphic match operator (=~) :: ( Typeable a , RegexContext TDFA.Regex T.Text a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => T.Text -> RE -> a (=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs --- | the regex-base monadic, polymorphic match operator+-- | the `regex-base` monadic, polymorphic match operator (=~~) :: ( Monad m , Functor m , Typeable a , RegexContext TDFA.Regex T.Text a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => T.Text -> RE@@ -142,6 +166,11 @@ -- $tutorial -- We have a regex tutorial at <http://tutorial.regex.uk>. +-- $macros+-- There are a number of RE macros and corresponding Haskell parsers+-- for parsing the matched text into appropriate Haskell types. See+-- the [Macros Tables](http://regex.uk/macros) for details.+ -- $options -- You can specify different compilation options by appending a -- to the name of an [re| ... |] or [ed| ... \/\/\/ ... |] quasi quoter@@ -152,7 +181,7 @@ -- -- will replace a @foo@ suffix of the argument text, of any -- capitalisation, with a (lower case) @bar@. If you need to specify the--- options dynamically, use the @[re_| ... |]@ and @[red_| ... \/\/\/ ... |]@+-- options dynamically, use the @[re_| ... |]@ and @[ed_| ... \/\/\/ ... |]@ -- quasi quoters, which generate functions that take an 'IsOption' option -- (e.g., a 'SimpleReOptions' value) and yields a 'RE' or 'SearchReplace' -- as apropriate. For example if you have a 'SimpleReOptions' value in@@ -171,3 +200,18 @@ -- $ed -- The @[ed|.*\/\/\/foo|]@ quasi quoters, with variants for specifing different -- options to the RE compiler (see "Text.RE.REOptions").++-- $ed+-- The -- | the @[ed| ... \/\/\/ ... |]@ quasi quoters; for example,+--+-- @[ed|${y}([0-9]{4})-0*${m}([0-9]{2})-0*${d}([0-9]{2})\/\/\/${d}\/${m}\/${y}|])@+--+-- represents a @SearchReplace@ that will convert a YYYY-MM-DD format date+-- into a DD\/MM\/YYYY format date.+--+-- The only difference betweem these quasi quoters is the RE options that are set,+-- using the same conventions as the @[re| ... |]@ quasi quoters.++-- $isregex+-- The 'IsRegex' class is used to abstact over the different regex back ends and+-- the text types they work with -- see "Text.RE.Tools.IsRegex" for details.
src/Text/RE/TDFA/Text/Lazy.hs view
@@ -20,18 +20,21 @@ -- * The 'SearchReplace' Operators , (*=~/) , (?=~/)- -- * Matches+ -- * The 'Matches' Type , Matches , matchesSource , allMatches , anyMatches , countMatches , matches- -- * Match+ -- * The 'Match' Type , Match , matchSource , matched , matchedText+ -- * The Macros and Parsers+ -- $macros+ , module Text.RE.TestBench.Parsers -- * The 'RE' Type , RE , reSource@@ -47,16 +50,38 @@ , escape , escapeWith , escapeREString- -- * The Classic rexex-base Match Operators+ -- * The Classic regex-base Match Operators , (=~) , (=~~)- -- * IsRegex- , IsRegex(..)- -- * The Quasi Quoters and Minor Functions+ -- * The re Quasi Quoters -- $re- , module Text.RE.ZeInternals.TDFA+ , re+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , reMS+ , reMI+ , reBS+ , reBI+ , re_+ -- * The Ed Quasi Quoters -- $ed- , module Text.RE.ZeInternals.SearchReplace.TDFA.Text.Lazy+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed+ , edMS+ , edMI+ , edBS+ , edBI+ , ed_+ -- * The cp Quasi Quoters+ , cp+ -- * IsRegex+ -- $isregex+ , module Text.RE.Tools.IsRegex ) where import qualified Data.Text.Lazy as TL@@ -64,10 +89,11 @@ import Prelude.Compat import Text.RE.REOptions import Text.RE.Replace-import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.TestBench.Parsers+import Text.RE.Tools.IsRegex+import Text.RE.ZeInternals import Text.RE.ZeInternals.SearchReplace.TDFA.Text.Lazy import Text.RE.ZeInternals.TDFA-import Text.RE.ZeInternals.Types.IsRegex import Text.Regex.Base import qualified Text.Regex.TDFA as TDFA @@ -102,7 +128,7 @@ (*=~/) = flip searchReplaceAll -- | search and replace the first occurrence only (if any) in the input text--- e.g., to prefix the first string of four hex digits in the imput text,+-- e.g., to prefix the first string of four hex digits in the input text, -- if any, with @0x@: -- -- @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@@@ -110,22 +136,20 @@ (?=~/) :: TL.Text -> SearchReplace RE TL.Text -> TL.Text (?=~/) = flip searchReplaceFirst --- | the regex-base polymorphic match operator+-- | the `regex-base` polymorphic match operator (=~) :: ( Typeable a , RegexContext TDFA.Regex TL.Text a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => TL.Text -> RE -> a (=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs --- | the regex-base monadic, polymorphic match operator+-- | the `regex-base` monadic, polymorphic match operator (=~~) :: ( Monad m , Functor m , Typeable a , RegexContext TDFA.Regex TL.Text a- , RegexMaker TDFA.Regex TDFA.CompOption TDFA.ExecOption String ) => TL.Text -> RE@@ -142,6 +166,11 @@ -- $tutorial -- We have a regex tutorial at <http://tutorial.regex.uk>. +-- $macros+-- There are a number of RE macros and corresponding Haskell parsers+-- for parsing the matched text into appropriate Haskell types. See+-- the [Macros Tables](http://regex.uk/macros) for details.+ -- $options -- You can specify different compilation options by appending a -- to the name of an [re| ... |] or [ed| ... \/\/\/ ... |] quasi quoter@@ -152,7 +181,7 @@ -- -- will replace a @foo@ suffix of the argument text, of any -- capitalisation, with a (lower case) @bar@. If you need to specify the--- options dynamically, use the @[re_| ... |]@ and @[red_| ... \/\/\/ ... |]@+-- options dynamically, use the @[re_| ... |]@ and @[ed_| ... \/\/\/ ... |]@ -- quasi quoters, which generate functions that take an 'IsOption' option -- (e.g., a 'SimpleReOptions' value) and yields a 'RE' or 'SearchReplace' -- as apropriate. For example if you have a 'SimpleReOptions' value in@@ -171,3 +200,18 @@ -- $ed -- The @[ed|.*\/\/\/foo|]@ quasi quoters, with variants for specifing different -- options to the RE compiler (see "Text.RE.REOptions").++-- $ed+-- The -- | the @[ed| ... \/\/\/ ... |]@ quasi quoters; for example,+--+-- @[ed|${y}([0-9]{4})-0*${m}([0-9]{2})-0*${d}([0-9]{2})\/\/\/${d}\/${m}\/${y}|])@+--+-- represents a @SearchReplace@ that will convert a YYYY-MM-DD format date+-- into a DD\/MM\/YYYY format date.+--+-- The only difference betweem these quasi quoters is the RE options that are set,+-- using the same conventions as the @[re| ... |]@ quasi quoters.++-- $isregex+-- The 'IsRegex' class is used to abstact over the different regex back ends and+-- the text types they work with -- see "Text.RE.Tools.IsRegex" for details.
+ stack-8.0.yaml view
@@ -0,0 +1,7 @@+resolver: lts-8.6+install-ghc: true+flags: {}+packages:+- '.'+system-ghc: false+extra-deps: []