packages feed

pcre-light 0.4.0.4 → 0.4.1.0

raw patch · 4 files changed

+4602/−21 lines, 4 filesdep +HUnitdep +containersdep +mtldep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: HUnit, containers, mtl, pcre-light

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Text.Regex.PCRE.Light: captureNames :: Regex -> [(ByteString, Int)]
+ Text.Regex.PCRE.Light.Char8: captureCount :: Regex -> Int
+ Text.Regex.PCRE.Light.Char8: captureNames :: Regex -> [(String, Int)]

Files

Text/Regex/PCRE/Light.hs view
@@ -10,7 +10,7 @@ -- Portability: H98 + CPP -- ----------------------------------------------------------------------- +-- -- A simple, portable binding to perl-compatible regular expressions -- (PCRE) via strict ByteStrings. --@@ -24,6 +24,7 @@         , compile, compileM         , match         , captureCount+        , captureNames          -- * Regex types and constructors externally visible @@ -82,6 +83,8 @@ #endif  import System.IO.Unsafe (unsafePerformIO)+import Data.List (sortBy)+import Data.Function (on)  -- Foreigns import Foreign (newForeignPtr, withForeignPtr)@@ -105,7 +108,7 @@ -- > let r = compile "^(b+|a){1,2}?bc" [] -- -- If the regular expression is invalid, an exception is thrown.--- If this is unsuitable, 'compileM' is availlable, which returns failure +-- If this is unsuitable, 'compileM' is availlable, which returns failure -- in a monad. -- -- To do case insentive matching,@@ -119,7 +122,7 @@ -- -- The arguments are: ----- * 'pat': A ByteString containing the regular expression to be compiled. +-- * 'pat': A ByteString containing the regular expression to be compiled. -- -- * 'flags', optional bit flags. If 'Nothing' is provided, defaults are used. --@@ -267,7 +270,7 @@ match :: Regex -> S.ByteString -> [PCREExecOption] -> Maybe [S.ByteString] match (Regex pcre_fp _) subject os = unsafePerformIO $ do   withForeignPtr pcre_fp $ \pcre_ptr -> do-    n_capt <- captureCount' pcre_ptr+    n_capt <- fullInfoInt pcre_ptr info_capturecount      -- The smallest  size  for ovector that will allow for n captured     -- substrings, in addition to the offsets  of  the  substring@@ -311,7 +314,7 @@     -- pair is used for the first capturing subpattern,  and  so on.  The     -- value returned  by pcre_exec() is one more than the highest num- bered     -- pair that has been set. For  example,  if  two  sub- strings  have been-    -- captured, the returned value is 3. +    -- captured, the returned value is 3.    where     -- The first element of a pair is set  to  the offset of the first@@ -325,12 +328,62 @@             end   = S.unsafeTake (fromIntegral (b-a)) start  +-- Wrapper around c_pcre_fullinfo for integer values+fullInfoInt pcre_ptr what =+  alloca $ \n_ptr -> do+    c_pcre_fullinfo pcre_ptr nullPtr what n_ptr+    return . fromIntegral =<< peek (n_ptr :: Ptr CInt)+++-- | 'captureCount'+--+-- Returns the number of captures in a 'Regex'. Correctly ignores non-capturing groups+-- like @(?:abc)@.+--+-- >>> captureCount (compile "(?<one>abc) (def) (?:non-captured) (?<three>ghi)" [])+-- 3 captureCount :: Regex -> Int-captureCount (Regex pcre_fp _) = unsafePerformIO $ do+captureCount (Regex pcre_fp _) = unsafePerformIO $+  withForeignPtr pcre_fp $ \pcre_ptr ->+    fullInfoInt pcre_ptr info_capturecount+++-- | 'captureNames'+--+-- Returns the names and numbers of all named subpatterns in the regular+-- expression. Groups are zero-indexed. Unnamed groups are counted, but don't appear in the+-- result list.+--+-- >>> captureNames (compile "(?<one>abc) (def) (?<three>ghi)")+-- [("one", 0), ("three", 2)]+captureNames :: Regex -> [(S.ByteString, Int)]+captureNames (Regex pcre_fp _) = unsafePerformIO $   withForeignPtr pcre_fp $ \pcre_ptr -> do-    captureCount' pcre_ptr+    count     <- fullInfoInt pcre_ptr info_namecount+    entrysize <- fullInfoInt pcre_ptr info_nameentrysize -captureCount' pcre_fp =-    alloca $ \n_ptr -> do -- (st :: Ptr CInt)-      c_pcre_fullinfo pcre_fp nullPtr info_capturecount n_ptr-      return . fromIntegral =<< peek (n_ptr :: Ptr CInt)+    buf <- alloca $ \n_ptr -> do+      c_pcre_fullinfo pcre_ptr nullPtr info_nametable n_ptr+      buf <- peek n_ptr+      S.packCStringLen (buf, count*entrysize)++    let results = split entrysize buf+        zeroIndexed = fmap (subtract 1) <$> results+        sorted = sortBy (compare `on` snd) zeroIndexed+    return sorted++  where+    -- Split the nametable buffer into entries. Each entry has a fixed size in+    -- bytes. The first two bytes in each entry store the pattern number in+    -- big-endian format, the bytes following that contain the nul-terminated+    -- name of the subpattern.+    split :: Int -> S.ByteString -> [(S.ByteString, Int)]+    split entrysize buf+      | S.null buf = []+      | otherwise =+        let+          (entry, tail) = S.splitAt entrysize buf+          idx = fromIntegral . S.index entry+          num = idx 0 * 256 + idx 1+          name = S.takeWhile (/= 0) $ S.drop 2 entry+        in (name, num) : split entrysize tail
Text/Regex/PCRE/Light/Char8.hs view
@@ -9,7 +9,7 @@ -- Portability: H98 + FFI -- ----------------------------------------------------------------------- +-- -- A simple, portable binding to perl-compatible regular expressions -- (PCRE) via 8-bit latin1 Strings. --@@ -22,6 +22,8 @@         -- * String interface         , compile, compileM         , match+        , S.captureCount+        , captureNames          -- * Regex types and constructors externally visible @@ -69,7 +71,7 @@  import qualified Data.ByteString.Char8 as S import qualified Text.Regex.PCRE.Light as S-import Text.Regex.PCRE.Light hiding (match, compile, compileM)+import Text.Regex.PCRE.Light hiding (match, compile, compileM, captureNames)  -- | 'compile' --@@ -77,7 +79,7 @@ -- The arguments are: -- -- * 'pat': A ByteString, which may or may not be zero-terminated,--- containing the regular expression to be compiled. +-- containing the regular expression to be compiled. -- -- * 'flags', optional bit flags. If 'Nothing' is provided, defaults are used. --@@ -125,15 +127,15 @@ -- -- * 'no_utf8_check'   - Do not check the pattern for UTF-8 validity ----- If compilation of the pattern fails, the 'Left' constructor is +-- If compilation of the pattern fails, the 'Left' constructor is -- returned with the error string. Otherwise an abstract type -- representing the compiled regular expression is returned. -- The regex is allocated via malloc on the C side, and will be -- deallocated by the runtime when the Haskell value representing it -- goes out of scope. ----- As regexes are often defined statically, GHC will compile them --- to null-terminated, strict C strings, enabling compilation of the +-- As regexes are often defined statically, GHC will compile them+-- to null-terminated, strict C strings, enabling compilation of the -- pattern without copying. This may be useful for very large patterns. -- -- See man pcreapi for more details.@@ -203,3 +205,15 @@            Nothing -> Nothing            Just x  -> Just (map S.unpack x) {-# INLINE match #-}+++-- | 'captureNames'+--+-- Returns the names and numbers of all named subpatterns in the regular+-- expression. Groups are zero-indexed. Unnamed groups are counted, but don't appear in the+-- result list.+--+-- >>> captureNames (compile "(?<one>abc) (def) (?<three>ghi)")+-- [("one", 0), ("three", 2)]+captureNames :: Regex -> [(String, Int)]+captureNames r = map (\(n,i) -> (S.unpack n, i)) $ S.captureNames r
pcre-light.cabal view
@@ -1,5 +1,5 @@ name: pcre-light-version: 0.4.0.4+version: 0.4.1.0 homepage: https://github.com/Daniel-Diaz/pcre-light synopsis: Portable regex library for Perl 5 compatible regular expressions description:@@ -9,7 +9,7 @@     expression pattern matching using the same syntax and semantics as Perl 5.     .     If installation fails reporting that you are missing the prce C library, try installing-    the @libpcre3-dev@ package (linux).+    the @libpcre3-dev@ package (linux) or @brew install pcre@ (MacOS).     . category:        Text license:         BSD3@@ -17,7 +17,7 @@ copyright:       (c) 2007-2010. Don Stewart <dons@galois.com> author:          Don Stewart maintainer:      Daniel Díaz <dhelta.diaz@gmail.com>-cabal-version: >= 1.2.0+cabal-version: >= 1.8.0 build-type:      Simple tested-with:     GHC == 7.8.3 extra-source-files: README.md@@ -26,6 +26,10 @@   description: Build with an old version of base (< 3)   default:     False +flag use-pkg-config+  default: False+  manual:  True+ library     exposed-modules: Text.Regex.PCRE.Light                      Text.Regex.PCRE.Light.Char8@@ -38,5 +42,22 @@     else         build-depends: base >= 3 && <= 5, bytestring >= 0.9 -    pkgconfig-depends: libpcre+    if flag(use-pkg-config)+      pkgconfig-depends: libpcre+    else+      extra-Libraries: pcre +test-suite unit+    type:                exitcode-stdio-1.0+    hs-source-dirs:      tests+    main-is:             Unit.hs+    if flag(old_base)+        build-depends: base < 3+    else+        build-depends: +            base >= 3 && <= 5+          , bytestring >= 0.9+          , containers >= 0.5.5.1+          , HUnit >= 1.2.5.2+          , mtl >= 2.1.3.2+          , pcre-light
+ tests/Unit.hs view
@@ -0,0 +1,4493 @@+{-# LANGUAGE OverloadedStrings #-}++import Text.Regex.PCRE.Light (compile,compileM,match,captureNames,captureCount)+import qualified Text.Regex.PCRE.Light.Char8 as String (compile,compileM,match)+import Text.Regex.PCRE.Light.Base++import qualified Data.ByteString.Char8 as S+import System.IO++import Test.HUnit+import System.Exit (exitFailure)+import Control.Monad (when)+import System.IO+import Data.Either+import qualified Data.Map as M++import System.IO.Unsafe+import Control.Exception+import Control.Monad.Except++assertBool' :: S.ByteString -> Bool -> Assertion+assertBool'  s = assertBool  (S.unpack s)++assertEqual' :: (Eq a, Show a) => S.ByteString -> a -> a -> Assertion+assertEqual' s = assertEqual (S.unpack s)++testLabel :: S.ByteString -> Test -> Test+testLabel  s = TestLabel (S.unpack s)++testRegex :: S.ByteString+     -> [PCREOption]+     -> [S.ByteString]+     -> [Maybe [S.ByteString]]+     -> Test++testRegex regex options inputs outputs = testLabel regex $+  TestCase $ do+     assertEqual' "Input/Output Length Check" (length inputs) (length outputs)++     assertBool' "ByteString regex compile" =<<+      case compile regex options of+        r -> return $+            and [ match r i [] == o+                | (i,o) <- zip inputs outputs ]++     assertBool' "ByteString regex compileM" =<<+      case compileM regex options of+        Left s -> do S.hPutStrLn stderr ("ERROR in ByteString in compileM " `S.append` (S.pack s))+                     return False+        Right r -> return $+            and [ match r i [] == o+                | (i,o) <- zip inputs outputs ]++     assertBool' "String regex" =<<+      case String.compile (S.unpack regex) options of+        r -> return $+            and [ String.match r i [] == o+                | (i,o) <- zip (map (S.unpack) inputs)+                               (map (fmap (map S.unpack)) outputs) ]++     assertBool' "String regex" =<<+      case String.compileM (S.unpack regex) options of+        Left s -> do S.hPutStrLn stderr ("ERROR in String compileM: " `S.append` (S.pack s))+                     return False+        Right r -> return $+            and [ String.match r i [] == o+                | (i,o) <- zip (map (S.unpack) inputs)+                               (map (fmap (map S.unpack)) outputs) ]++testCaptures :: Int+     -> S.ByteString+     -> [(S.ByteString, Int)]+     -> Test+testCaptures expectedTotalCaptures regex expectedCaptureNames = testLabel regex $+    TestCase $ do+        r <- case compileM regex [] of+            Left s -> assertFailure ("ERROR in ByteString in compileM " ++ s)+            Right r -> return r+        assertEqual' "Capture group name mismatch" expectedCaptureNames (captureNames r)+        assertEqual' "Capture count mismatch" expectedTotalCaptures (captureCount r)++main :: IO ()+main = do counts <- runTestTT tests+          when (errors counts > 0 || failures counts > 0) exitFailure++tests :: Test+tests = TestList++    [ testRegex "the quick brown fox" []+           [ "the quick brown fox"+           , "The quick brown FOX"+           , "What do you know about the quick brown fox?"+           , "What do you know about THE QUICK BROWN FOX?"+           ]+           [ Just ["the quick brown fox"]+           , Nothing+           , Just ["the quick brown fox"]+           , Nothing+           ]++    , testLabel "compile failure" $+            TestCase $ (assertBool' "compile failure" $+                Left ("nothing to repeat" ) == compileM "*" [])++    , testLabel "compile failure" $+            TestCase $ (assertEqual' "compile failure"+                            (Just ("Text.Regex.PCRE.Light: Error in regex: nothing to repeat"))+                            (fmap (head . S.lines) . unsafePerformIO $ do+                                handle (\e -> return (Just (S.pack $ displayException (e :: SomeException))))+                                    (compile "*" [] `seq` return Nothing)))++--  , testRegex "\0*" [] -- the embedded null in the pattern seems to be a problem+--      ["\0\0\0\0"]+--      [Just ["\0\0\0\0"]]++    , testRegex "\1*" [] -- the embedded null in the pattern seems to be a problem+        ["\1\1\1\1"]+        [Just ["\1\1\1\1"]]++    , testRegex "The quick brown fox" [caseless]+           ["the quick brown fox"+           ,"The quick brown FOX"+           ,"What do you know about the quick brown fox?"+           ,"What do you know about THE QUICK BROWN FOX?"+           ]+           [ Just ["the quick brown fox"]+           , Just ["The quick brown FOX"]+           , Just ["the quick brown fox"]+           , Just ["THE QUICK BROWN FOX"]+           ]++     , testRegex "a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" []+           ["abxyzpqrrrabbxyyyypqAzz"+           ,"abxyzpqrrrabbxyyyypqAzz"+           ,"aabxyzpqrrrabbxyyyypqAzz"+           ,"aaabxyzpqrrrabbxyyyypqAzz"+           ,"aaaabxyzpqrrrabbxyyyypqAzz"+           ,"abcxyzpqrrrabbxyyyypqAzz"+           ,"aabcxyzpqrrrabbxyyyypqAzz"+           ,"aaabcxyzpqrrrabbxyyyypAzz"+           ,"aaabcxyzpqrrrabbxyyyypqAzz"+           ,"aaabcxyzpqrrrabbxyyyypqqAzz"+           ,"aaabcxyzpqrrrabbxyyyypqqqAzz"+           ,"aaabcxyzpqrrrabbxyyyypqqqqAzz"+           ,"aaabcxyzpqrrrabbxyyyypqqqqqAzz"+           ,"aaabcxyzpqrrrabbxyyyypqqqqqqAzz"+           ,"aaaabcxyzpqrrrabbxyyyypqAzz"+           ,"abxyzzpqrrrabbxyyyypqAzz"+           ,"aabxyzzzpqrrrabbxyyyypqAzz"+           ,"aaabxyzzzzpqrrrabbxyyyypqAzz"+           ,"aaaabxyzzzzpqrrrabbxyyyypqAzz"+           ,"abcxyzzpqrrrabbxyyyypqAzz"+           ,"aabcxyzzzpqrrrabbxyyyypqAzz"+           ,"aaabcxyzzzzpqrrrabbxyyyypqAzz"+           ,"aaaabcxyzzzzpqrrrabbxyyyypqAzz"+           ,"aaaabcxyzzzzpqrrrabbbxyyyypqAzz"+           ,"aaaabcxyzzzzpqrrrabbbxyyyyypqAzz"+           ,"aaabcxyzpqrrrabbxyyyypABzz"+           ,"aaabcxyzpqrrrabbxyyyypABBzz"+           ,">>>aaabxyzpqrrrabbxyyyypqAzz"+           ,">aaaabxyzpqrrrabbxyyyypqAzz"+           ,">>>>abcxyzpqrrrabbxyyyypqAzz"+           ,"abxyzpqrrabbxyyyypqAzz"+           ,"abxyzpqrrrrabbxyyyypqAzz"+           ,"abxyzpqrrrabxyyyypqAzz"+           ,"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz"+           ,"aaaabcxyzzzzpqrrrabbbxyyypqAzz"+           ,"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz"+           ]++           [ Just ["abxyzpqrrrabbxyyyypqAzz"]+           , Just ["abxyzpqrrrabbxyyyypqAzz"]+           , Just ["aabxyzpqrrrabbxyyyypqAzz"]+           , Just ["aaabxyzpqrrrabbxyyyypqAzz"]+           , Just ["aaaabxyzpqrrrabbxyyyypqAzz"]+           , Just ["abcxyzpqrrrabbxyyyypqAzz"]+           , Just ["aabcxyzpqrrrabbxyyyypqAzz"]+           , Just ["aaabcxyzpqrrrabbxyyyypAzz"]+           , Just ["aaabcxyzpqrrrabbxyyyypqAzz"]+           , Just ["aaabcxyzpqrrrabbxyyyypqqAzz"]+           , Just ["aaabcxyzpqrrrabbxyyyypqqqAzz"]+           , Just ["aaabcxyzpqrrrabbxyyyypqqqqAzz"]+           , Just ["aaabcxyzpqrrrabbxyyyypqqqqqAzz"]+           , Just ["aaabcxyzpqrrrabbxyyyypqqqqqqAzz"]+           , Just ["aaaabcxyzpqrrrabbxyyyypqAzz"]+           , Just ["abxyzzpqrrrabbxyyyypqAzz"]+           , Just ["aabxyzzzpqrrrabbxyyyypqAzz"]+           , Just ["aaabxyzzzzpqrrrabbxyyyypqAzz"]+           , Just ["aaaabxyzzzzpqrrrabbxyyyypqAzz"]+           , Just ["abcxyzzpqrrrabbxyyyypqAzz"]+           , Just ["aabcxyzzzpqrrrabbxyyyypqAzz"]+           , Just ["aaabcxyzzzzpqrrrabbxyyyypqAzz"]+           , Just ["aaaabcxyzzzzpqrrrabbxyyyypqAzz"]+           , Just ["aaaabcxyzzzzpqrrrabbbxyyyypqAzz"]+           , Just ["aaaabcxyzzzzpqrrrabbbxyyyyypqAzz"]+           , Just ["aaabcxyzpqrrrabbxyyyypABzz"]+           , Just ["aaabcxyzpqrrrabbxyyyypABBzz"]+           , Just ["aaabxyzpqrrrabbxyyyypqAzz"]+           , Just ["aaaabxyzpqrrrabbxyyyypqAzz"]+           , Just ["abcxyzpqrrrabbxyyyypqAzz"]+           , Nothing+           , Nothing+           , Nothing+           , Nothing+           , Nothing+           , Nothing+           ]++    , testRegex "^(abc){1,2}zz" []+        ["abczz"+        ,"abcabczz"+        ,"zz"+        ,"abcabcabczz"+        ,">>abczz"]+        [ Just ["abczz","abc"]+        , Just ["abcabczz", "abc"]+        , Nothing+        , Nothing+        , Nothing ]++    , testRegex "^(b+?|a){1,2}?c" []+        ["bc",+         "bbc",+         "bbbc",+         "bac",+         "bbac",+         "aac",+         "abbbbbbbbbbbc",+         "bbbbbbbbbbbac",+         "aaac",+         "abbbbbbbbbbbac"]++        [Just ["bc", "b"],+         Just ["bbc", "b"],+         Just ["bbbc", "bb"],+         Just ["bac", "a"],+         Just ["bbac", "a"],+         Just ["aac", "a"],+         Just ["abbbbbbbbbbbc", "bbbbbbbbbbb"],+         Just ["bbbbbbbbbbbac", "a"],+         Nothing,+         Nothing]++    , testRegex "^(b+|a){1,2}c" []+        ["bc",+         "bbc",+         "bbbc",+         "bac",+         "bbac",+         "aac",+         "abbbbbbbbbbbc",+         "bbbbbbbbbbbac",+         "aaac",+         "abbbbbbbbbbbac"]+        [Just ["bc", "b"],+         Just ["bbc", "bb"],+         Just ["bbbc", "bbb"],+         Just ["bac", "a"],+         Just ["bbac", "a"],+         Just ["aac", "a"],+         Just ["abbbbbbbbbbbc", "bbbbbbbbbbb"],+         Just ["bbbbbbbbbbbac", "a"],+         Nothing,+         Nothing]++    , testRegex "^(b+|a){1,2}?bc" []+        ["bbc"]+        [Just ["bbc", "b"]]++    , testRegex "^(b*|ba){1,2}?bc" []+        ["babc",+         "bbabc",+         "bababc",+         "bababbc",+         "babababc"]+        [Just ["babc","ba"],+         Just ["bbabc","ba"],+         Just ["bababc","ba"],+         Nothing,+         Nothing]++    , testRegex "^(ba|b*){1,2}?bc" []+        ["babc",+         "bbabc",+         "bababc",+         "bababbc",+         "babababc"]+        [Just ["babc","ba"],+         Just ["bbabc","ba"],+         Just ["bababc","ba"],+         Nothing,+         Nothing]++    , testRegex "^[ab\\]cde]" []+        ["athing",+         "bthing",+         "]thing",+         "cthing",+         "dthing",+         "ething",+         "fthing",+         "[thing",+         "\\\\thing"]+        [Just ["a"],+         Just ["b"],+         Just ["]"],+         Just ["c"],+         Just ["d"],+         Just ["e"],+         Nothing,+         Nothing,+         Nothing]++    , testRegex "^[]cde]" []+        ["]thing",+         "cthing",+         "dthing",+         "ething",+         "athing",+         "fthing"]+        [Just ["]"],+         Just ["c"],+         Just ["d"],+         Just ["e"],+         Nothing,+         Nothing]++    , testRegex "^[^ab\\]cde]" []+        ["fthing",+         "[thing",+         "\\\\thing",+         "athing",+         "bthing",+         "]thing",+         "cthing",+         "dthing",+         "ething"]+        [Just ["f"],+         Just ["["],+         Just ["\\"],+         Nothing,+         Nothing,+         Nothing,+         Nothing,+         Nothing,+         Nothing]++    , testRegex "^\129" []+        ["\129"]+        [Just ["\x81"]]++    , testRegex "^\255" []+        ["\255"]+        [Just ["\xff"]]++    , testRegex "^[0-9]+$" []+        ["0",+         "1",+         "2",+         "3",+         "4",+         "5",+         "6",+         "7",+         "8",+         "9",+         "10",+         "100",+         "abc"]+        [Just ["0"],+         Just ["1"],+         Just ["2"],+         Just ["3"],+         Just ["4"],+         Just ["5"],+         Just ["6"],+         Just ["7"],+         Just ["8"],+         Just ["9"],+         Just ["10"],+         Just ["100"],+         Nothing]++    , testRegex "^.*nter" []+        ["enter",+         "inter",+         "uponter"]+        [Just ["enter"],+         Just ["inter"],+         Just ["uponter"]]++    , testRegex "^xxx[0-9]+$" []+        ["xxx0",+         "xxx1234",+         "xxx"]+        [Just ["xxx0"],+         Just ["xxx1234"],+         Nothing]++    , testRegex "^.+[0-9][0-9][0-9]$" []+        ["x123",+         "xx123",+         "123456",+         "123",+         "x1234"]+        [Just ["x123"],+         Just ["xx123"],+         Just ["123456"],+         Nothing,+         Just ["x1234"]]++    , testRegex "^.+?[0-9][0-9][0-9]$" []+        ["x123",+         "xx123",+         "123456",+         "123",+         "x1234"]+        [Just ["x123"],+         Just ["xx123"],+         Just ["123456"],+         Nothing,+         Just ["x1234"]]++    -- test matching more than 1 subpattern+    , testRegex "^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" []+        ["abc!pqr=apquxz.ixr.zzz.ac.uk",+         "!pqr=apquxz.ixr.zzz.ac.uk",+         "abc!=apquxz.ixr.zzz.ac.uk",+         "abc!pqr=apquxz:ixr.zzz.ac.uk",+         "abc!pqr=apquxz.ixr.zzz.ac.ukk"]+        [Just ["abc!pqr=apquxz.ixr.zzz.ac.uk", "abc", "pqr"],+         Nothing,+         Nothing,+         Nothing,+         Nothing]++    , testRegex ":" []+        ["Well, we need a colon: somewhere",+         "*** Fail if we don't"]+        [Just [":"],+         Nothing]++    , testRegex "([\\da-f:]+)$" [caseless]+        ["0abc",+         "abc",+         "fed",+         "E",+         "::",+         "5f03:12C0::932e",+         "fed def",+         "Any old stuff",+         "*** Failers",+         "0zzz",+         "gzzz",+         "fed\x20",+         "Any old rubbish"]+        [Just ["0abc", "0abc"],+         Just ["abc", "abc"],+         Just ["fed", "fed"],+         Just ["E", "E"],+         Just ["::", "::"],+         Just ["5f03:12C0::932e", "5f03:12C0::932e"],+         Just ["def", "def"],+         Just ["ff", "ff"],+         Nothing,+         Nothing,+         Nothing,+         Nothing,+         Nothing]++    , testRegex "^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" []+        [".1.2.3",+         "A.12.123.0",+         ".1.2.3333",+         "1.2.3",+         "1234.2.3"]+        [Just [".1.2.3", "1", "2", "3"],+         Just ["A.12.123.0", "12", "123", "0"],+         Nothing,+         Nothing,+         Nothing]++    , testRegex "^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$" []+        ["1 IN SOA non-sp1 non-sp2(",+         "1    IN    SOA    non-sp1    non-sp2   (",+         "1IN SOA non-sp1 non-sp2("]+        [Just ["1 IN SOA non-sp1 non-sp2(", "1", "non-sp1", "non-sp2"],+         Just ["1    IN    SOA    non-sp1    non-sp2   (", "1", "non-sp1", "non-sp2"],+         Nothing]++    , testRegex "^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$" []+        ["a.",+         "Z.",+         "2.",+         "ab-c.pq-r.",+         "sxk.zzz.ac.uk.",+         "x-.y-.",+         "*** Failers",+         "-abc.peq."]+        [Just ["a."],+         Just ["Z."],+         Just ["2."],+         Just ["ab-c.pq-r.", ".pq-r"],+         Just ["sxk.zzz.ac.uk.", ".uk"],+         Just ["x-.y-.", ".y-"],+         Nothing,+         Nothing]++    , testRegex "^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" []+        ["*.a",+         "*.b0-a",+         "*.c3-b.c",+         "*.c-a.b-c",+         "*** Failers",+         "*.0",+         "*.a-",+         "*.a-b.c-",+         "*.c-a.0-c"]+        [Just ["*.a"],+         Just ["*.b0-a", "0-a"],+         Just ["*.c3-b.c", "3-b", ".c"],+         Just ["*.c-a.b-c", "-a", ".b-c", "-c"],+         Nothing,+         Nothing,+         Nothing,+         Nothing,+         Nothing]++    , testRegex "^(?=ab(de))(abd)(e)" []+        ["abde"]+        [Just ["abde", "de", "abd", "e"]]++    , testRegex "^(?!(ab)de|x)(abd)(f)" []+        ["abdf"]+        [Just ["abdf", "", "abd", "f"]]++    , testRegex "^(?=(ab(cd)))(ab)" []+        ["abcd"]+        [Just ["ab", "abcd", "cd", "ab"]]++    , testRegex "^[\\da-f](\\.[\\da-f])*$" [caseless]+        ["a.b.c.d",+         "A.B.C.D",+         "a.b.c.1.2.3.C"]+        [Just ["a.b.c.d", ".d"],+         Just ["A.B.C.D", ".D"],+         Just ["a.b.c.1.2.3.C", ".C"]]++    , testRegex "^\".*\"\\s*(;.*)?$" []+        ["\"1234\"",+         "\"abcd\" ;",+         "\"\" ; rhubarb",+         "*** Failers",+         "\\\"1234\\\" : things"]+        [Just ["\"1234\""],+         Just ["\"abcd\" ;", ";"],+         Just ["\"\" ; rhubarb", "; rhubarb"],+         Nothing,+         Nothing]++    , testRegex "^$" []+        ["",+         "*** Failers"]+        [Just [""],+         Nothing]++    , testRegex "   ^    a   (?# begins with a)  b\\sc (?# then b c) $ (?# then end)" [extended]+        ["ab c",+         "*** Failers",+         "abc",+         "ab cde"]+        [Just ["ab c"],+         Nothing,+         Nothing,+         Nothing]++    , testRegex "(?x)   ^    a   (?# begins with a)  b\\sc (?# then b c) $ (?# then end)" []+        ["ab c",+         "*** Failers",+         "abc",+         "ab cde"]+        [Just ["ab c"],+         Nothing,+         Nothing,+         Nothing]++    , testRegex "^   a\\ b[c ]d       $" [extended]+        ["a bcd",+         "a b d",+         "*** Failers",+         "abcd",+         "ab d"]+        [Just ["a bcd"],+         Just ["a b d"],+         Nothing,+         Nothing,+         Nothing]++    , testRegex "^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$" []+        ["abcdefhijklm"]+        [Just ["abcdefhijklm",+               "abc", "bc",+               "c", "def",+               "ef", "f",+               "hij", "ij",+               "j", "klm",+               "lm", "m"]]++    , testRegex "^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$" []+        ["abcdefhijklm"]+        [Just ["abcdefhijklm",+             "bc", "c", "ef", "f", "ij", "j", "lm", "m"]]++    , testRegex "^[.^$|()*+?{,}]+" []+        [".^$(*+)|{?,?}"]+        [Just [".^$(*+)|{?,?}"]]++    , testRegex "^a*\\w" []+        ["z",+         "az",+         "aaaz",+         "a",+         "aa",+         "aaaa",+         "a+",+         "aa+"]+        [Just ["z"],+         Just ["az"],+         Just ["aaaz"],+         Just ["a"],+         Just ["aa"],+         Just ["aaaa"],+         Just ["a"],+         Just ["aa"]]++    , testRegex "^a*?\\w" []+        ["z",+         "az",+         "aaaz",+         "a",+         "aa",+         "aaaa",+         "a+",+         "aa+"]+        [Just ["z"],+         Just ["a"],+         Just ["a"],+         Just ["a"],+         Just ["a"],+         Just ["a"],+         Just ["a"],+         Just ["a"]]++    , testRegex "^a+\\w" []+        ["az",+         "aaaz",+         "aa",+         "aaaa",+         "aa+"]+        [Just ["az"],+         Just ["aaaz"],+         Just ["aa"],+         Just ["aaaa"],+         Just ["aa"]]++    , testRegex "^a+?\\w" []+        ["az",+         "aaaz",+         "aa",+         "aaaa",+         "aa+"]+        [Just ["az"],+         Just ["aa"],+         Just ["aa"],+         Just ["aa"],+         Just ["aa"]]++    , testRegex "^\\d{8}\\w{2,}" []+        ["1234567890",+         "12345678ab",+         "12345678__",+         "*** Failers",+         "1234567"]+        [Just ["1234567890"],+         Just ["12345678ab"],+         Just ["12345678__"],+         Nothing,+         Nothing]++    , testRegex "^[aeiou\\d]{4,5}$" []+        ["uoie",+         "1234",+         "12345",+         "aaaaa",+         "*** Failers",+         "123456"]+        [Just ["uoie"],+         Just ["1234"],+         Just ["12345"],+         Just ["aaaaa"],+         Nothing,+         Nothing]++    , testRegex "^[aeiou\\d]{4,5}?" []+        ["uoie",+         "1234",+         "12345",+         "aaaaa",+         "123456"]+        [Just ["uoie"],+         Just ["1234"],+         Just ["1234"],+         Just ["aaaa"],+         Just ["1234"]]++    , testRegex "\\A(abc|def)=(\\1){2,3}\\Z" []+        ["abc=abcabc",+         "def=defdefdef",+         "*** Failers",+         "abc=defdef"]+        [Just ["abc=abcabc", "abc", "abc"],+         Just ["def=defdefdef", "def", "def"],+         Nothing,+         Nothing]++    , testRegex "^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$" []+        ["abcdefghijkcda2",+         "abcdefghijkkkkcda2"]+        [Just ["abcdefghijkcda2", "a", "b",+         "c", "d", "e", "f", "g", "h", "i", "j", "k", "cd"],++         Just ["abcdefghijkkkkcda2", "a", "b", "c", "d",+             "e", "f", "g", "h", "i", "j", "k", "cd"]]++    , testRegex "(cat(a(ract|tonic)|erpillar)) \\1()2(3)" []+        ["cataract cataract23",+         "catatonic catatonic23",+         "caterpillar caterpillar23"]++        [Just ["cataract cataract23", "cataract", "aract", "ract", "", "3"],++         Just ["catatonic catatonic23", "catatonic", "atonic", "tonic", "", "3"],++         Just ["caterpillar caterpillar23", "caterpillar", "erpillar", "", "", "3"]]++    , testRegex "^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]" []+        ["From abcd  Mon Sep 01 12:33:02 1997"]+        [Just ["From abcd  Mon Sep 01 12:33", "abcd"]]++    , testRegex "^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d" []+        ["From abcd  Mon Sep 01 12:33:02 1997",+         "From abcd  Mon Sep  1 12:33:02 1997",+         "*** Failers",+         "From abcd  Sep 01 12:33:02 1997"]+        [Just ["From abcd  Mon Sep 01 12:33", "Sep "],+         Just ["From abcd  Mon Sep  1 12:33", "Sep  "],+         Nothing,+         Nothing]++    , testRegex "\\w+(?=\t)" []+        ["the quick brown\t fox"]+        [Just ["brown"]]++    , testRegex "foo(?!bar)(.*)" []+        ["foobar is foolish see?"]+        [Just ["foolish see?", "lish see?"]]++    , testRegex "(?:(?!foo)...|^.{0,2})bar(.*)" []+        ["foobar crowbar etc",+         "barrel",+         "2barrel",+         "A barrel"]+        [Just ["rowbar etc", " etc"],+         Just ["barrel",     "rel"],+         Just ["2barrel",    "rel"],+         Just ["A barrel",   "rel"]]++    , testRegex "^(\\D*)(?=\\d)(?!123)" []+        ["abc456",+         "*** Failers",+         "abc123"]+        [Just ["abc", "abc"],+         Nothing,+         Nothing]++    , testRegex "^(a)\\1{2,3}(.)" []+        ["aaab",+         "aaaab",+         "aaaaab",+         "aaaaaab"]+        [Just ["aaab", "a","b"],+         Just ["aaaab","a","b"],+         Just ["aaaaa","a","a"],+         Just ["aaaaa","a","a"]]++    , testRegex "(?!^)abc" []+        ["the abc",+         "*** Failers",+         "abc"]+        [Just ["abc"],+         Nothing,+         Nothing]++    , testRegex "(?=^)abc" []+        ["abc",+         "*** Failers",+         "the abc"]+        [Just ["abc"],+         Nothing,+         Nothing]++    , testRegex "^[ab]{1,3}(ab*|b)" []+        ["aabbbbb"]+        [Just ["aabb", "b"]]++    , testRegex "^[ab]{1,3}?(ab*|b)" []+        ["aabbbbb"]+        [Just ["aabbbbb", "abbbbb"]]++    , testRegex "^[ab]{1,3}?(ab*?|b)" []+        ["aabbbbb"]+        [Just ["aa", "a"]]++    , testRegex "^[ab]{1,3}(ab*?|b)" []+        ["aabbbbb"]+        [Just ["aabb", "b"]]++    , testRegex "^(cow|)\\1(bell)" []+        ["cowcowbell",+         "bell",+         "*** Failers",+         "cowbell"]+        [Just ["cowcowbell", "cow", "bell"],+         Just ["bell", "", "bell"],+         Nothing,+         Nothing]++    , testRegex "^\\s" []+        ["\o40abc",+         "\nabc",+         "\rabc",+         "\tabc",+         "abc"]+        [Just [" "],+         Just ["\x0a"],+         Just ["\x0d"],+         Just ["\x09"],+         Nothing]++    , testRegex "^(a|)\\1*b" []+        ["ab",+         "aaaab",+         "b",+         "acb"]+        [Just ["ab", "a"],+         Just ["aaaab", "a"],+         Just ["b", ""],+         Nothing]++    , testRegex "^(a|)\\1+b" []+        ["aab",+         "aaaab",+         "b",+         "*** Failers",+         "ab"]+        [Just ["aab", "a"],+         Just ["aaaab", "a"],+         Just ["b", ""],+         Nothing,+         Nothing]++    , testRegex "^(a|)\\1?b" []+        ["ab",+         "aab",+         "b",+         "acb"]+        [Just ["ab", "a"],+         Just ["aab", "a"],+         Just ["b", ""],+         Nothing]++    , testRegex "^(a|)\\1{2}b" []+        ["aaab",+         "b",+         "ab",+         "aab",+         "aaaab"]+        [Just ["aaab", "a"],+         Just ["b", ""],+         Nothing,+         Nothing,+         Nothing]++    , testRegex "^(a|)\\1{2,3}b" []+        ["aaab",+         "aaaab",+         "b",+         "ab",+         "aab",+         "aaaaab"]+        [Just ["aaab", "a"],+         Just ["aaaab", "a"],+         Just ["b", ""],+         Nothing,+         Nothing,+         Nothing]++    , testRegex "ab{1,3}bc" []+        ["abbbbc",+         "abbbc",+         "abbc",+         "abc",+         "abbbbbc"]+        [Just ["abbbbc"],+         Just ["abbbc"],+         Just ["abbc"],+         Nothing,+         Nothing]++    , testRegex "([^.]*)\\.([^:]*):[T ]+(.*)" []+        ["track1.title:TBlah blah blah"]+        [Just ["track1.title:TBlah blah blah", "track1", "title", "Blah blah blah"]]++    , testRegex "([^.]*)\\.([^:]*):[T ]+(.*)" [caseless]+        ["track1.title:TBlah blah blah"]+        [Just ["track1.title:TBlah blah blah", "track1", "title", "Blah blah blah"]]++    , testRegex "([^.]*)\\.([^:]*):[t ]+(.*)" [caseless]+        ["track1.title:TBlah blah blah"]+        [Just ["track1.title:TBlah blah blah", "track1", "title", "Blah blah blah"]]++    , testRegex "^[W-c]+$" []+        ["WXY_^abc",+         "wxy"]+        [Just ["WXY_^abc"],+         Nothing]++    , testRegex "^[W-c]+$" [caseless]+        ["WXY_^abc",+         "wxy_^ABC"]+        [Just ["WXY_^abc"],+         Just ["wxy_^ABC"]]++    , testRegex "^[\\x3f-\\x5F]+$" [caseless]+        ["WXY_^abc",+         "wxy_^ABC"]+        [Just ["WXY_^abc"],+         Just ["wxy_^ABC"]]++    , testRegex "^abc$" []+        ["abc",+         "qqq\\nabc",+         "abc\\nzzz",+         "qqq\\nabc\\nzzz"]+        [Just ["abc"],+         Nothing,+         Nothing,+         Nothing]++    , testRegex "(?:b)|(?::+)" []+        ["b::c",+         "c::b"]+        [Just ["b"],+         Just ["::"]]++    , testRegex "[-az]+" []+        ["az-",+         "*** Failers",+         "b"]+        [Just ["az-"],+         Just ["a"],+         Nothing]++    , testRegex "[az-]+" []+        ["za-",+         "*** Failers",+         "b"]+        [Just ["za-"],+         Just ["a"],+         Nothing]++    , testRegex "[a\\-z]+" []+        ["a-z",+         "*** Failers",+         "b"]+        [Just ["a-z"],+         Just ["a"],+         Nothing]++    , testRegex "[a-z]+" []+        ["abcdxyz"]+        [Just ["abcdxyz"]]++    , testRegex "[\\d-]+" []+        ["12-34",+         "aaa"]+        [Just ["12-34"],+         Nothing]+    , testRegex "[\\d-z]+" []+        ["12-34z",+         "aaa"]+        [Just ["12-34z"],+         Nothing]++    , testRegex "\\x20Z" []+        ["the Zoo",+         "*** Failers",+         "Zulu"]+        [Just [" Z"],+         Nothing,+         Nothing]++    , testRegex "(abc)\\1" [caseless]+        ["abcabc",+         "ABCabc",+         "abcABC"]+        [Just ["abcabc", "abc"],+         Just ["ABCabc", "ABC"],+         Just ["abcABC", "abc"]]++    , testRegex "ab{3cd" []+        ["ab{3cd"]+        [Just ["ab{3cd"]]++    , testRegex "ab{3,cd" []+        ["ab{3,cd"]+        [Just ["ab{3,cd"]]++    , testRegex "ab{3,4a}cd" []+        ["ab{3,4a}cd"]+        [Just ["ab{3,4a}cd"]]++    , testRegex "{4,5a}bc" []+        ["{4,5a}bc"]+        [Just ["{4,5a}bc"]]++    , testRegex "abc$" []+        ["abc",+         "abc\n",+         "*** Failers",+         "abc\ndef"]+        [Just ["abc"],+         Just ["abc"],+         Nothing,+         Nothing]++    , testRegex "(abc)\\123" []+        ["abc\x53"]+        [Just ["abcS", "abc"]]++    , testRegex "(abc)\\223" []+        ["abc\x93"]+        [Just ["abc\x93", "abc"]]++    , testRegex "(abc)\\323" []+        ["abc\xd3"]+        [Just ["abc\xd3", "abc"]]++    , testRegex "(abc)\\100" []+        ["abc\x40",+         "abc\o100"]+        [Just ["abc@", "abc"],+         Just ["abc@", "abc"]]++    , testRegex "(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123" []+        ["abcdefghijkllS"]+        [Just ["abcdefghijkllS",+             "a",+             "b",+             "c",+             "d",+             "e",+             "f",+             "g",+             "h",+             "i",+             "j",+             "k",+             "l"]]++     , testRegex "(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\\123" []+        ["abcdefghijk\o12S"]+        [Just ["abcdefghijk\x0aS",+             "a",+             "b",+             "c",+             "d",+             "e",+             "f",+             "g",+             "h",+             "i",+             "j",+             "k"]]++    , testRegex "ab\\idef" []+        ["abidef"]+        [Just ["abidef"]]++    , testRegex "a{0}bc" []+        ["bc"]+        [Just ["bc"]]++    , testRegex "(a|(bc)){0,0}?xyz" []+        ["xyz"]+        [Just ["xyz"]]++    , testRegex "(?s)a.b" []+        ["a\nb"]+        [Just ["a\nb"]]++    , testRegex "^([^a])([^\\b])([^c]*)([^d]{3,4})" []+        ["baNOTccccd",+         "baNOTcccd",+         "baNOTccd",+         "bacccd",+         "anything",+         "b\bc   ",+         "baccd"]+        [Just ["baNOTcccc", "b", "a", "NOT", "cccc"],+         Just ["baNOTccc", "b", "a", "NOT", "ccc"],+         Just ["baNOTcc", "b", "a", "NO", "Tcc"],+         Just ["baccc", "b", "a", "", "ccc"],+         Nothing,+         Nothing,+         Nothing]++    , testRegex "^\\d{8,}\\@.+[^k]$" []+        ["12345678@a.b.c.d",+         "123456789@x.y.z",+         "*** Failers",+         "12345678@x.y.uk",+         "1234567@a.b.c.d       "]+        [Just ["12345678@a.b.c.d"],+         Just ["123456789@x.y.z"],+         Nothing,+         Nothing,+         Nothing]++    , testRegex "(a)\\1{8,}" []+        ["aaaaaaaaa",+         "aaaaaaaaaa",+         "*** Failers",+         "aaaaaaa   "]+        [Just ["aaaaaaaaa", "a"],+         Just ["aaaaaaaaaa", "a"],+         Nothing,+         Nothing]++    , testRegex "[^a]" []+        ["aaaabcd",+         "aaAabcd "]+        [Just ["b"],+         Just ["A"]]++    , testRegex "[^a]" [caseless]+        ["aaaabcd",+         "aaAabcd "]+        [Just ["b"],+         Just ["b"]]++    , testRegex "[^az]" []+        ["aaaabcd",+         "aaAabcd "]+        [Just ["b"],+         Just ["A"]]++    , testRegex "[^az]" [caseless]+        ["aaaabcd",+         "aaAabcd "]+        [Just ["b"],+         Just ["b"]]++    , testRegex "P[^*]TAIRE[^*]{1,6}?LL" []+        ["xxxxxxxxxxxPSTAIREISLLxxxxxxxxx"]+        [Just ["PSTAIREISLL"]]++    , testRegex "P[^*]TAIRE[^*]{1,}?LL" []+        ["xxxxxxxxxxxPSTAIREISLLxxxxxxxxx"]+        [Just ["PSTAIREISLL"]]++    , testRegex "(.*?)(\\d+)" []+        ["I have 2 numbers: 53147"]+        [Just ["I have 2", "I have ", "2"]]++    , testRegex "(.*)(\\d+)$" []+        ["I have 2 numbers: 53147"]+        [Just ["I have 2 numbers: 53147", "I have 2 numbers: 5314", "7"]]++    , testRegex "(.*?)(\\d+)$" []+        ["I have 2 numbers: 53147"]+        [Just ["I have 2 numbers: 53147", "I have 2 numbers: ", "53147"]]++    , testRegex "(.*)\\b(\\d+)$" []+        ["I have 2 numbers: 53147"]+        [Just ["I have 2 numbers: 53147", "I have 2 numbers: ", "53147"]]++    , testRegex "(.*\\D)(\\d+)$" []+        ["I have 2 numbers: 53147"]+        [Just ["I have 2 numbers: 53147", "I have 2 numbers: ", "53147"]]++    , testRegex "word (?:[a-zA-Z0-9]+ ){0,10}otherword" []+        ["word cat dog elephant mussel cow horse canary baboon snake shark otherword",+         "word cat dog elephant mussel cow horse canary baboon snake shark"]+        [Just ["word cat dog elephant mussel cow horse canary baboon snake shark otherword"],+         Nothing]++    , testRegex "word (?:[a-zA-Z0-9]+ ){0,300}otherword" []+        ["word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope"]+        [Nothing]+    , testRegex "^(a){0,0}" []+        ["bcd",+         "abc",+         "aab     "]+        [Just [""],+         Just [""],+         Just [""]]++    , testRegex "^(a){0,1}" []+        ["bcd",+         "abc",+         "aab  "]+        [Just [""],+         Just ["a", "a"],+         Just ["a", "a"]]++    , testRegex "^(a){0,2}" []+        ["bcd",+         "abc",+         "aab  "]+        [Just [""],+         Just ["a", "a"],+         Just ["aa", "a"]]++    , testRegex "^(a){0,3}" []+        ["bcd",+         "abc",+         "aab",+         "aaa   "]+        [Just [""],+         Just ["a", "a"],+         Just ["aa", "a"],+         Just ["aaa", "a"]]++    , testRegex "^(a){0,3}" []+        ["bcd",+         "abc",+         "aab",+         "aaa   "]+        [Just [""],+         Just ["a", "a"],+         Just ["aa", "a"],+         Just ["aaa", "a"]]++    , testRegex "^(a){0,}" []+        ["bcd",+         "abc",+         "aab",+         "aaa",+         "aaaaaaaa    "]+        [Just [""],+         Just ["a", "a"],+         Just ["aa", "a"],+         Just ["aaa", "a"],+         Just ["aaaaaaaa", "a"]]++    , testRegex "^(a){1,1}" []+        ["bcd",+         "abc",+         "aab  "]+        [Nothing,+         Just ["a", "a"],+         Just ["a", "a"]]++    , testRegex "^(a){1,2}" []+        ["bcd",+         "abc",+         "aab  "]+        [Nothing,+         Just ["a", "a"],+         Just ["aa", "a"]]++    , testRegex "^(a){1,3}" []+        ["bcd",+         "abc",+         "aab",+         "aaa   "]+        [Nothing,+         Just ["a", "a"],+         Just ["aa", "a"],+         Just ["aaa", "a"]]++    , testRegex ".*\\.gif" []+        ["borfle\nbib.gif\nno"]+        [Just ["bib.gif"]]++    , testRegex ".{0,}\\.gif" []+        ["borfle\nbib.gif\nno"]+        [Just ["bib.gif"]]++    , testRegex ".*\\.gif" [multiline]+        ["borfle\nbib.gif\nno"]+        [Just ["bib.gif"]]++    , testRegex ".*\\.gif" [dotall]+        ["borfle\nbib.gif\nno"]+        [Just ["borfle\nbib.gif"]]++    , testRegex ".*$" [multiline]+        ["borfle\nbib.gif\nno"]+        [Just ["borfle"]]++    , testRegex ".*$" [dotall]+        ["borfle\nbib.gif\nno"]+        [Just ["borfle\nbib.gif\nno"]]++    , testRegex ".*$" [multiline]+        ["borfle\nbib.gif\nno\\n"]+        [Just ["borfle"]]++    , testRegex "(?ms)^B" []+        ["abc\nB"]+        [Just ["B"]]++    , testRegex "(?s)B$" []+        ["B\n"]+        [Just ["B"]]++    , testRegex "^[abcdefghijklmnopqrstuvwxy0123456789]" []+        ["n",+         "z "]+        [Just ["n"],+         Nothing]++    , testRegex "abcde{0,0}" []+        ["abcd",+         "abce  "]+        [Just ["abcd"],+         Nothing]++    , testRegex "^(b+?|a){1,2}?c" []+        ["bac",+         "bbac",+         "bbbac",+         "bbbbac",+         "bbbbbac "]+        [Just ["bac","a"],+         Just ["bbac","a"],+         Just ["bbbac","a"],+         Just ["bbbbac","a"],+         Just ["bbbbbac","a"]]++    , testRegex "(AB)*?\\1" []+        ["ABABAB"]+        [Just ["ABAB", "AB"]]++    , testRegex "(.*(.)?)*" []+        ["abcd"]+        [Just ["abcd", ""]]++{-+    , testRegex "(?:a|)*\\d" []+        ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",+         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4"]+        [Nothing,+         Just ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4"]]+-}++    , testRegex "^(?:a(?:(?:))+)+" []+        ["aaaa"]+        [Just ["aaaa"]]++    , testRegex "^(a()+)+" []+        ["aaaa"]+        [Just ["aaaa", "a", ""]]++    , testRegex "^(?:a(?:(?:))*)*" []+        ["aaaa"]+        [Just ["aaaa"]]++    , testRegex "^(a()*)*" []+        ["aaaa"]+        [Just ["aaaa", "a", ""]]++    , testRegex "^(a){1,}" []+        ["bcd",+         "abc",+         "aab",+         "aaa",+         "aaaaaaaa    "]+        [Nothing,+         Just ["a", "a"],+         Just ["aa", "a"],+         Just ["aaa", "a"],+         Just ["aaaaaaaa", "a"]]++    , testRegex "(?s)(.*X|^B)" []+        ["abcde\n1234Xyz",+         "BarFoo ",+         "*** Failers ",+         "abcde\nBar  "]+        [Just ["abcde\n1234X", "abcde\n1234X"],+         Just ["B", "B"],+         Nothing,+         Nothing]++    , testRegex "(?s:.*X|^B)" []+        ["abcde\n1234Xyz",+         "BarFoo ",+         "*** Failers ",+         "abcde\nBar  "]+        [Just ["abcde\n1234X"],+         Just ["B"],+         Nothing,+         Nothing]++    , testRegex "\\w{3}(?<!bar)foo" []+        ["catfood",+         "*** Failers",+         "foo",+         "barfoo",+         "towbarfoo"]+        [Just ["catfoo"],+         Nothing,+         Nothing,+         Nothing,+         Nothing]++    , testRegex "(?>(\\.\\d\\d[1-9]?))\\d+" []+        ["1.230003938",+         "1.875000282",+         "1.235 "]+        [Just [".230003938", ".23"],+         Just [".875000282", ".875"],+         Nothing]++    , testRegex "^((?>\\w+)|(?>\\s+))*$" []+        ["now is the time for all good men to come to the aid of the party",+         "this is not a line with only words and spaces!"]+        [Just ["now is the time for all good men to come to the aid of the party", "party"],+         Nothing]++    , testRegex "((?>\\d+))(\\w)" []+        ["12345a",+         "12345+ "]+        [Just ["12345a", "12345", "a"],+         Nothing]++    , testRegex "(?>a+)b" []+        ["aaab"]+        [Just ["aaab"]]++    , testRegex "((?>a+)b)" []+        ["aaab"]+        [Just ["aaab", "aaab"]]++    , testRegex "(?>(a+))b" []+        ["aaab"]+        [Just ["aaab", "aaa"]]+    , testRegex "(?>b)+" []+        ["aaabbbccc"]+        [Just ["bbb"]]++    , testRegex "(?>a+|b+|c+)*c" []+        ["aaabbbbccccd"]+        [Just ["aaabbbbc"]]++    , testRegex "(?:(a)|b)(?(1)A|B)" []+        ["aA",+         "bB",+         "aB",+         "bA    "]+        [Just ["aA", "a"],+         Just ["bB"],+         Nothing,+         Nothing]++    , testRegex "^(a)?(?(1)a|b)+$" []+        ["aa",+         "b",+--       "bb  ", -- ?+         "ab   "]+        [Just ["aa", "a"],+         Just ["b"],+--       Just ["bb"],+         Nothing]++    , testRegex "^(?(?=abc)\\w{3}:|\\d\\d)$" []+        ["abc:",+         "12",+         "123",+         "xyz    "]+        [Just ["abc:"],+         Just ["12"],+         Nothing,+         Nothing]++    , testRegex "(?(?<!foo)cat|bar)" []+        ["foobar",+         "cat",+         "fcat",+         "focat   ",+         "foocat  "]+        [Just ["bar"],+         Just ["cat"],+         Just ["cat"],+         Just ["cat"],+         Nothing]++    , testRegex "^(?(2)a|(1)(2))+$" []+        ["12",+         "12a",+         "12aa",+         "*** Failers",+         "1234    "]+        [Just ["12", "1", "2"],+         Just ["12a", "1", "2"],+         Just ["12aa", "1", "2"],+         Nothing,+         Nothing]++    , testRegex "(?<=foo\\n)^bar" [multiline]+        ["foo\nbar",+         "*** Failers",+         "bar",+         "baz\nbar   "]+        [Just ["bar"],+         Nothing,+         Nothing,+         Nothing]++    , testRegex "(?<=(?<!foo)bar)baz" []+        ["barbaz",+         "barbarbaz ",+         "koobarbaz ",+         "*** Failers",+         "baz",+         "foobarbaz "]+        [Just ["baz"],+         Just ["baz"],+         Just ["baz"],+         Nothing,+         Nothing,+         Nothing]++{-+    , testRegex "^(a\\1?){4}$" []+        ["a",+         "aa",+         "aaa",+         "aaaa",+         "aaaaa",+         "aaaaaaa",+         "aaaaaaaa",+         "aaaaaaaaa",+         "aaaaaaaaaa",+         "aaaaaaaaaaa",+         "aaaaaaaaaaaa",+         "aaaaaaaaaaaaa",+         "aaaaaaaaaaaaaa",+         "aaaaaaaaaaaaaaa",+         "aaaaaaaaaaaaaaaa               "]+        [Nothing,+         Nothing,+         Nothing,+         Just ["aaaa", "a"],+         Just ["aaaaa", "a"],+         Just ["aaaaaaa", "a"],+         Nothing,+         Nothing,+         Just ["aaaaaaaaaa", "aaaa"],+         Nothing,+         Nothing,+         Nothing,+         Nothing,+         Nothing,+         Nothing]+-}++    , testRegex "abc" []+        ["abc",+         "xabcy",+         "ababc",+         "*** Failers",+         "xbc",+         "axc",+         "abx"]+        [Just ["abc"],+         Just ["abc"],+         Just ["abc"],+         Nothing,+         Nothing,+         Nothing,+         Nothing]++    , testRegex "ab*c" []+        ["abc"]+        [Just ["abc"]]+    , testRegex "ab*bc" []+        ["abc",+         "abbc",+         "abbbbc"]+        [Just ["abc"],+         Just ["abbc"],+         Just ["abbbbc"]]++    , testRegex ".{1}" []+        ["abbbbc"]+        [Just ["a"]]++    , testRegex ".{3,4}" []+        ["abbbbc"]+        [Just ["abbb"]]++    , testRegex "ab{0,}bc" []+        ["abbbbc"]+        [Just ["abbbbc"]]++    , testRegex "ab+bc" []+        ["abbc",+         "abc",+         "abq"]+        [Just ["abbc"],+         Nothing,+         Nothing]++    , testRegex "ab{1,}bc" []+        []+        []++    , testRegex "ab+bc" []+        ["abbbbc"]+        [Just ["abbbbc"]]++    , testRegex "ab{1,}bc" []+        ["abbbbc"]+        [Just ["abbbbc"]]++    , testRegex "ab{1,3}bc" []+        ["abbbbc"]+        [Just ["abbbbc"]]++    , testRegex "ab{3,4}bc" []+        ["abbbbc"]+        [Just ["abbbbc"]]++    , testRegex "ab{4,5}bc" []+        ["*** Failers",+         "abq",+         "abbbbc"]+        [Nothing,+         Nothing,+         Nothing]++    , testRegex "ab?bc" []+        ["abbc",+         "abc"]+        [Just ["abbc"],+         Just ["abc"]]++    , testRegex "ab{0,1}bc" []+        ["abc"]+        [Just ["abc"]]++    , testRegex "ab?bc" []+        []+        []++    , testRegex "ab?c" []+        ["abc"]+        [Just ["abc"]]++    , testRegex "ab{0,1}c" []+        ["abc"]+        [Just ["abc"]]++    , testRegex "^abc$" []+        ["abc",+         "abbbbc",+         "abcc"]+        [Just ["abc"],+         Nothing,+         Nothing]++    , testRegex "^abc" []+        ["abcc"]+        [Just ["abc"]]++    , testRegex "^abc$" []+        []+        []++    , testRegex "abc$" []+        ["aabc",+         "*** Failers",+         "aabc",+         "aabcd"]+        [Just ["abc"],+         Nothing,+         Just ["abc"],+         Nothing]++    , testRegex "^" []+        ["abc"]+        [Just [""]]+    ,++    testRegex "$" []+        ["abc"]+        [Just [""]]+    ,++    testRegex "a.c" []+        ["abc",+         "axc"]+        [Just ["abc"],+         Just ["axc"]]+    ,++    testRegex "a.*c" []+        ["axyzc"]+        [Just ["axyzc"]]+    ,++    testRegex "a[bc]d" []+        ["abd",+         "*** Failers",+         "axyzd",+         "abc"]+        [Just ["abd"],+         Nothing,+         Nothing,+         Nothing]+    ,++    testRegex "a[b-d]e" []+        ["ace"]+        [Just ["ace"]]+    ,++    testRegex "a[b-d]" []+        ["aac"]+        [Just ["ac"]]+    ,++    testRegex "a[-b]" []+        ["a-"]+        [Just ["a-"]]+    ,++    testRegex "a[b-]" []+        ["a-"]+        [Just ["a-"]]+    ,+++    testRegex "a]" []+        ["a]"]+        [Just ["a]"]]+    ,+++    testRegex "a[]]b" []+        ["a]b"]+        [Just ["a]b"]]+    ,++    testRegex "a[^bc]d" []+        ["aed",+         "*** Failers",+         "abd",+         "abd"]+        [Just ["aed"],+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "a[^-b]c" []+        ["adc"]+        [Just ["adc"]]+    ,++    testRegex "a[^]b]c" []+        ["adc",+         "*** Failers",+         "a-c",+         "a]c"]+        [Just ["adc"],+         Nothing,+         Just ["a-c"],+         Nothing]+    ,+++    testRegex "\\ba\\b" []+        ["a-",+         "-a",+         "-a-"]+        [Just ["a"],+         Just ["a"],+         Just ["a"]]+    ,+++    testRegex "\\by\\b" []+        ["*** Failers",+         "xy",+         "yz",+         "xyz"]+        [Nothing,+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "\\Ba\\B" []+        ["*** Failers",+         "a-",+         "-a",+         "-a-"]+        [Just ["a"],+         Nothing,+         Nothing,+         Nothing]+    ,++    testRegex "\\By\\b" []+        ["xy"]+        [Just ["y"]]+    ,+++    testRegex "\\by\\B" []+        ["yz"]+        [Just ["y"]]+    ,+++    testRegex "\\By\\B" []+        ["xyz"]+        [Just ["y"]]+    ,++    testRegex "\\w" []+        ["a"]+        [Just ["a"]]+    ,+++    testRegex "\\W" []+        ["-",+         "*** Failers",+         "-",+         "a"]+        [Just ["-"],+         Just ["*"],+         Just ["-"],+         Nothing]+    ,+++    testRegex "a\\sb" []+        ["a b"]+        [Just ["a b"]]+    ,+++    testRegex "a\\Sb" []+        ["a-b",+         "*** Failers",+         "a-b",+         "a b"]+        [Just ["a-b"],+         Nothing,+         Just ["a-b"],+         Nothing]+    ,+++    testRegex "\\d" []+        ["1"]+        [Just ["1"]]+    ,+++    testRegex "\\D" []+        ["-",+         "*** Failers",+         "-",+         "1"]+        [Just ["-"],+         Just ["*"],+         Just ["-"],+         Nothing]+    ,+++    testRegex "[\\w]" []+        ["a"]+        [Just ["a"]]+    ,+++    testRegex "[\\W]" []+        ["-",+         "*** Failers",+         "-",+         "a"]+        [Just ["-"],+         Just ["*"],+         Just ["-"],+         Nothing]+    ,+++    testRegex "a[\\s]b" []+        ["a b"]+        [Just ["a b"]]+    ,+++    testRegex "a[\\S]b" []+        ["a-b",+         "*** Failers",+         "a-b",+         "a b"]+        [Just ["a-b"],+         Nothing,+         Just ["a-b"],+         Nothing]+    ,++    testRegex "[\\d]" []+        ["1"]+        [Just ["1"]]+    ,+++    testRegex "[\\D]" []+        ["-",+         "*** Failers",+         "-",+         "1"]+        [Just ["-"],+         Just ["*"],+         Just ["-"],+         Nothing]+    ,+++    testRegex "ab|cd" []+        ["abc",+         "abcd"]+        [Just ["ab"],+         Just ["ab"]]+    ,++++    testRegex "$b" []+        []+        []+    ,+++    testRegex "a\\(b" []+        ["a(b"]+        [Just ["a(b"]]+    ,+++    testRegex "a\\(*b" []+        ["ab",+         "a((b"]+        [Just ["ab"],+         Just ["a((b"]]+    ,+++    testRegex "((a))" []+        ["abc"]+        [Just ["a", "a", "a"]]+    ,+++    testRegex "(a)b(c)" []+        ["abc"]+        [Just ["abc", "a", "c"]]++    ,+    testRegex "a+b+c" []+        ["aabbabc"]+        [Just ["abc"]]+    ,+++    testRegex "a{1,}b{1,}c" []+        ["aabbabc"]+        [Just ["abc"]]+    ,+++    testRegex "a.+?c" []+        ["abcabc"]+        [Just ["abc"]]+    ,+++    testRegex "(a+|b)*" []+        ["ab"]+        [Just ["ab", "b"]]+    ,+++    testRegex "(a+|b){0,}" []+        ["ab"]+        [Just ["ab", "b"]]+    ,+++    testRegex "(a+|b)+" []+        ["ab"]+        [Just ["ab","b"]]+    ,+++    testRegex "(a+|b){1,}" []+        ["ab"]+        [Just ["ab", "b"]]+    ,+++    testRegex "(a+|b)?" []+        ["ab"]+        [Just ["a", "a"]]+    ,+++    testRegex "(a+|b){0,1}" []+        ["ab"]+        [Just ["a", "a"]]+    ,+++    testRegex "[^ab]*" []+        ["cde"]+        [Just ["cde"]]++    ,++    testRegex "abc" []+        ["b"]+        [Nothing]+    ,+++    testRegex "a*" []+        [""]+        [Just [""]]+    ,+++    testRegex "([abc])*d" []+        ["abbbcd"]+        [Just ["abbbcd", "c"]]+    ,+++    testRegex "([abc])*bcd" []+        ["abcd"]+        [Just ["abcd", "a"]]+    ,+++    testRegex "a|b|c|d|e" []+        ["e"]+        [Just ["e"]]+    ,+++    testRegex "(a|b|c|d|e)f" []+        ["ef"]+        [Just ["ef", "e"]]+    ,+++    testRegex "abcd*efg" []+        ["abcdefg"]+        [Just ["abcdefg"]]+    ,+++    testRegex "ab*" []+        ["xabyabbbz",+         "xayabbbz"]+        [Just ["ab"],+         Just ["a"]]+    ,+++    testRegex "(ab|cd)e" []+        ["abcde"]+        [Just ["cde", "cd"]]+    ,+++    testRegex "[abhgefdc]ij" []+        ["hij"]+        [Just ["hij"]]++    , testRegex "^(ab|cd)e" []+        []+        []+    ,++    testRegex "(abc|)ef" []+        ["abcdef"]+        [Just ["ef", ""]]+    ,+++    testRegex "(a|b)c*d" []+        ["abcd"]+        [Just ["bcd", "b"]]+    ,+++    testRegex "(ab|ab*)bc" []+        ["abc"]+        [Just ["abc", "a"]]+    ,+++    testRegex "a([bc]*)c*" []+        ["abc"]+        [Just ["abc", "bc"]]+    ,+++    testRegex "a([bc]*)(c*d)" []+        ["abcd"]+        [Just ["abcd", "bc", "d"]]+    ,+++    testRegex "a([bc]+)(c*d)" []+        ["abcd"]+        [Just ["abcd", "bc", "d"]]+    ,+++    testRegex "a([bc]*)(c+d)" []+        ["abcd"]+        [Just ["abcd", "b", "cd"]]+    ,+++    testRegex "a[bcd]*dcdcde" []+        ["adcdcde"]+        [Just ["adcdcde"]]+    ,+++    testRegex "a[bcd]+dcdcde" []+        ["*** Failers",+         "abcde",+         "adcdcde"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "(ab|a)b*c" []+        ["abc"]+        [Just ["abc", "ab"]]++    ,++    testRegex "((a)(b)c)(d)" []+        ["abcd"]+        [Just ["abcd", "abc", "a", "b", "d"]]+    ,+++    testRegex "[a-zA-Z_][a-zA-Z0-9_]*" []+        ["alpha"]+        [Just ["alpha"]]+    ,+++    testRegex "^a(bc+|b[eh])g|.h$" []+        ["abh"]+        [Just ["bh"]]+    ,+++    testRegex "(bc+d$|ef*g.|h?i(j|k))" []+        ["effgz",+         "ij",+         "reffgz",+         "*** Failers",+         "effg",+         "bcdd"]+        [Just ["effgz", "effgz"],+         Just ["ij", "ij", "j"],+         Just ["effgz", "effgz"],+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "((((((((((a))))))))))" []+        ["a"]+        [Just ["a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a"]]+    ,+++    testRegex "((((((((((a))))))))))\\10" []+        ["aa"]+        [Just ["aa", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a"]]+    ,+++    testRegex "(((((((((a)))))))))" []+        ["a"]+        [Just ["a", "a", "a", "a", "a", "a", "a", "a", "a", "a"]]+    ,+++    testRegex "multiple words of text" []+        ["*** Failers",+         "aa",+         "uh-uh"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "multiple words" []+        ["multiple words, yeah"]+        [Just ["multiple words"]]+    ,+++    testRegex "(.*)c(.*)" []+        ["abcde"]+        [Just ["abcde", "ab", "de"]]+    ,++    testRegex "\\((.*), (.*)\\)" []+        ["(a, b)"]+        [Just ["(a, b)", "a", "b"]]+    ,+++    testRegex "[k]" []+        []+        []+    ,+++    testRegex "abcd" []+        ["abcd"]+        [Just ["abcd"]]+    ,+++    testRegex "a(bc)d" []+        ["abcd"]+        [Just ["abcd", "bc"]]+    ,+++    testRegex "a[-]?c" []+        ["ac"]+        [Just ["ac"]]+    ,+++    testRegex "(abc)\\1" []+        ["abcabc"]+        [Just ["abcabc", "abc"]]+    ,+++    testRegex "([a-c]*)\\1" []+        ["abcabc"]+        [Just ["abcabc", "abc"]]+    ,+++    testRegex "(a)|\\1" []+        ["a",+         "*** Failers",+         "ab",+         "x"]+        [Just ["a", "a"],+         Just ["a", "a"],+         Just ["a", "a"],+         Nothing]+    ,+++    testRegex "(([a-c])b*?\\2)*" []+        ["ababbbcbc"]+        [Just ["ababb", "bb", "b"]]+    ,+++    testRegex "(([a-c])b*?\\2){3}" []+        ["ababbbcbc"]+        [Just ["ababbbcbc", "cbc", "c"]]+    ,+    testRegex "((\\3|b)\\2(a)x)+" []+        ["aaaxabaxbaaxbbax"]+        [Just ["bbax", "bbax", "b", "a"]]+    ,+++    testRegex "((\\3|b)\\2(a)){2,}" []+        ["bbaababbabaaaaabbaaaabba"]+        [Just ["bbaaaabba", "bba", "b", "a"]]+    ,+++    testRegex "abc" [caseless]+        ["ABC",+         "XABCY",+         "ABABC",+         "*** Failers",+         "aaxabxbaxbbx",+         "XBC",+         "AXC",+         "ABX"]+        [Just ["ABC"],+         Just ["ABC"],+         Just ["ABC"],+         Nothing,+         Nothing,+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "ab*c" [caseless]+        ["ABC"]+        [Just ["ABC"]]+    ,+++    testRegex "ab*bc" [caseless]+        ["ABC",+         "ABBC"]+        [Just ["ABC"],+         Just ["ABBC"]]+    ,+++    testRegex "ab*?bc" [caseless]+        ["ABBBBC"]+        [Just ["ABBBBC"]]+    ,+++    testRegex "ab{0,}?bc" [caseless]+        ["ABBBBC"]+        [Just ["ABBBBC"]]+    ,+++    testRegex "ab+?bc" [caseless]+        ["ABBC"]+        [Just ["ABBC"]]+    ,+++    testRegex "ab+bc" [caseless]+        ["*** Failers",+         "ABC",+         "ABQ"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "ab{1,}bc" [caseless]+        []+        []+    ,++    testRegex "ab+bc" [caseless]+        ["ABBBBC"]+        [Just ["ABBBBC"]]+    ,+++    testRegex "ab{1,}?bc" [caseless]+        ["ABBBBC"]+        [Just ["ABBBBC"]]+    ,+++    testRegex "ab{1,3}?bc" [caseless]+        ["ABBBBC"]+        [Just ["ABBBBC"]]+    ,+++    testRegex "ab{3,4}?bc" [caseless]+        ["ABBBBC"]+        [Just ["ABBBBC"]]+    ,+++    testRegex "ab{4,5}?bc" [caseless]+        ["*** Failers",+         "ABQ",+         "ABBBBC"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "ab??bc" [caseless]+        ["ABBC",+         "ABC"]+        [Just ["ABBC"],+         Just ["ABC"]]+    ,+++    testRegex "ab{0,1}?bc" [caseless]+        ["ABC"]+        [Just ["ABC"]]+    ,+++    testRegex "ab??bc" [caseless]+        []+        []+    ,+++    testRegex "ab??c" [caseless]+        ["ABC"]+        [Just ["ABC"]]+    ,++    testRegex "ab{0,1}?c" [caseless]+        ["ABC"]+        [Just ["ABC"]]+    ,+    testRegex "^abc$" [caseless]+        ["ABC",+         "*** Failers",+         "ABBBBC",+         "ABCC"]+        [Just ["ABC"],+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "^abc" [caseless]+        ["ABCC"]+        [Just ["ABC"]]+    ,+++    testRegex "^abc$" [caseless]+        []+        []+    ,+++    testRegex "abc$" [caseless]+        ["AABC"]+        [Just ["ABC"]]+    ,+++    testRegex "^" [caseless]+        ["ABC"]+        [Just [""]]+    ,+++    testRegex "$" [caseless]+        ["ABC"]+        [Just [""]]+    ,+++    testRegex "a.c" [caseless]+        ["ABC",+         "AXC"]+        [Just ["ABC"],+         Just ["AXC"]]+    ,+++    testRegex "a.*?c" [caseless]+        ["AXYZC"]+        [Just ["AXYZC"]]+    ,+++    testRegex "a.*c" [caseless]+        ["*** Failers",+         "AABC",+         "AXYZD"]+        [Nothing,+         Just ["AABC"],+         Nothing]+    ,+++    testRegex "a[bc]d" [caseless]+        ["ABD"]+        [Just ["ABD"]]+    ,++    testRegex "a[b-d]e" [caseless]+        ["ACE",+         "ABC",+         "ABD"]+        [Just ["ACE"],+         Nothing,+         Nothing]+    ,+++    testRegex "a[b-d]" [caseless]+        ["AAC"]+        [Just ["AC"]]+    ,+++    testRegex "a[-b]" [caseless]+        ["A-"]+        [Just ["A-"]]+    ,+++    testRegex "a[b-]" [caseless]+        ["A-"]+        [Just ["A-"]]+    ,+++    testRegex "a]" [caseless]+        ["A]"]+        [Just ["A]"]]+    ,+++    testRegex "a[]]b" [caseless]+        ["A]B"]+        [Just ["A]B"]]+    ,+++    testRegex "a[^bc]d" [caseless]+        ["AED"]+        [Just ["AED"]]+    ,+++    testRegex "a[^-b]c" [caseless]+        ["ADC",+         "ABD",+         "A-C"]+        [Just ["ADC"],+         Nothing,+         Nothing]+    ,+++    testRegex "a[^]b]c" [caseless]+        ["ADC"]+        [Just ["ADC"]]+    ,+++    testRegex "ab|cd" [caseless]+        ["ABC",+         "ABCD"]+        [Just ["AB"],+         Just ["AB"]]++    ,+    testRegex "()ef" [caseless]+        ["DEF"]+        [Just ["EF", ""]]+    ,+++    testRegex "$b" [caseless]+        ["A]C",+         "B"]+        [Nothing,+         Nothing]+    ,+++    testRegex "a\\(b" [caseless]+        ["A(B"]+        [Just ["A(B"]]+    ,+++    testRegex "a\\(*b" [caseless]+        ["AB",+         "A((B"]+        [Just ["AB"],+         Just ["A((B"]]+    ,++++    testRegex "((a))" [caseless]+        ["ABC"]+        [Just ["A", "A", "A"]]+    ,+++    testRegex "(a)b(c)" [caseless]+        ["ABC"]+        [Just ["ABC", "A", "C"]]+    ,+++    testRegex "a+b+c" [caseless]+        ["AABBABC"]+        [Just ["ABC"]]+    ,+++    testRegex "a{1,}b{1,}c" [caseless]+        ["AABBABC"]+        [Just ["ABC"]]+    ,+++    testRegex "a.+?c" [caseless]+        ["ABCABC"]+        [Just ["ABC"]]+    ,++    testRegex "a.*?c" [caseless]+        ["ABCABC"]+        [Just ["ABC"]]+    ,+++    testRegex "a.{0,5}?c" [caseless]+        ["ABCABC"]+        [Just ["ABC"]]+    ,+++    testRegex "(a+|b)*" [caseless]+        ["AB"]+        [Just ["AB", "B"]]+    ,+++    testRegex "(a+|b){0,}" [caseless]+        ["AB"]+        [Just ["AB", "B"]]+    ,+++    testRegex "(a+|b)+" [caseless]+        ["AB"]+        [Just ["AB","B"]]+    ,+++    testRegex "(a+|b){1,}" [caseless]+        ["AB"]+        [Just ["AB", "B"]]+    ,+++    testRegex "(a+|b)?" [caseless]+        ["AB"]+        [Just ["A", "A"]]+    ,+++    testRegex "(a+|b){0,1}" [caseless]+        ["AB"]+        [Just ["A", "A"]]+    ,+++    testRegex "(a+|b){0,1}?" [caseless]+        ["AB"]+        [Just [""]]+    ,+++    testRegex "[^ab]*" [caseless]+        ["CDE"]+        [Just ["CDE"]]+    ,++    testRegex "abc" [caseless]+        []+        []+    ,+++    testRegex "a*" [caseless]+        [""]+        [Just [""]]+    ,+++    testRegex "([abc])*d" [caseless]+        ["ABBBCD"]+        [Just ["ABBBCD", "C"]]+    ,+++    testRegex "([abc])*bcd" [caseless]+        ["ABCD"]+        [Just ["ABCD","A"]]+    ,+++    testRegex "a|b|c|d|e" [caseless]+        ["E"]+        [Just ["E"]]+    ,+++    testRegex "(a|b|c|d|e)f" [caseless]+        ["EF"]+        [Just ["EF", "E"]]+    ,+++    testRegex "abcd*efg" [caseless]+        ["ABCDEFG"]+        [Just ["ABCDEFG"]]+    ,+++    testRegex "ab*" [caseless]+        ["XABYABBBZ",+         "XAYABBBZ"]+        [Just ["AB"],+         Just ["A"]]+    ,+++    testRegex "(ab|cd)e" [caseless]+        ["ABCDE"]+        [Just ["CDE", "CD"]]+    ,+++    testRegex "[abhgefdc]ij" [caseless]+        ["HIJ"]+        [Just ["HIJ"]]+    ,+++    testRegex "^(ab|cd)e" [caseless]+        ["ABCDE"]+        [Nothing]+    ,+++    testRegex "(abc|)ef" [caseless]+        ["ABCDEF"]+        [Just ["EF", ""]]+    ,+++    testRegex "(a|b)c*d" [caseless]+        ["ABCD"]+        [Just ["BCD", "B"]]+    ,+++    testRegex "(ab|ab*)bc" [caseless]+        ["ABC"]+        [Just ["ABC", "A"]]+    ,+++    testRegex "a([bc]*)c*" [caseless]+        ["ABC"]+        [Just ["ABC", "BC"]]+    ,+++    testRegex "a([bc]*)(c*d)" [caseless]+        ["ABCD"]+        [Just ["ABCD","BC","D"]]+    ,+++    testRegex "a([bc]+)(c*d)" [caseless]+        ["ABCD"]+        [Just ["ABCD","BC","D"]]+    ,+++    testRegex "a([bc]*)(c+d)" [caseless]+        ["ABCD"]+        [Just ["ABCD","B","CD"]]+    ,+++    testRegex "a[bcd]*dcdcde" [caseless]+        ["ADCDCDE"]+        [Just ["ADCDCDE"]]+    ,++    testRegex "a[bcd]+dcdcde" [caseless]+        []+        []+    ,++    testRegex "(ab|a)b*c" [caseless]+        ["ABC"]+        [Just ["ABC", "AB"]]+    ,+++    testRegex "((a)(b)c)(d)" [caseless]+        ["ABCD"]+        [Just ["ABCD", "ABC", "A", "B", "D"]]+    ,+++    testRegex "[a-zA-Z_][a-zA-Z0-9_]*" [caseless]+        ["ALPHA"]+        [Just ["ALPHA"]]+    ,+++    testRegex "^a(bc+|b[eh])g|.h$" [caseless]+        ["ABH"]+        [Just ["BH"]]+    ,+++    testRegex "(bc+d$|ef*g.|h?i(j|k))" [caseless]+        ["EFFGZ",+         "IJ",+         "REFFGZ",+         "*** Failers",+         "ADCDCDE",+         "EFFG",+         "BCDD"]+        [Just ["EFFGZ", "EFFGZ"],+         Just ["IJ", "IJ", "J"],+         Just ["EFFGZ", "EFFGZ"],+         Nothing,+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "((((((((((a))))))))))" [caseless]+        ["A"]+        [Just ["A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A"]]+    ,+++    testRegex "((((((((((a))))))))))\\10" [caseless]+        ["AA"]+        [Just ["AA", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A"]]+    ,+++    testRegex "(((((((((a)))))))))" [caseless]+        ["A"]+        [Just ["A", "A", "A", "A", "A", "A", "A", "A", "A", "A"]]+    ,+++    testRegex "(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))" [caseless]+        ["A"]+        [Just ["A", "A"]]+    ,+++    testRegex "(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))" [caseless]+        ["C"]+        [Just ["C", "C"]]+    ,+++    testRegex "multiple words of text" [caseless]+        ["AA",+         "UH-UH"]+        [Nothing,+         Nothing]+    ,+++    testRegex "multiple words" [caseless]+        ["MULTIPLE WORDS, YEAH"]+        [Just ["MULTIPLE WORDS"]]+    ,+++    testRegex "(.*)c(.*)" [caseless]+        ["ABCDE"]+        [Just ["ABCDE", "AB", "DE"]]+    ,+++    testRegex "\\((.*), (.*)\\)" [caseless]+        ["(A, B)"]+        [Just ["(A, B)", "A", "B"]]+    ,+++    testRegex "[k]" [caseless]+        []+        []+    ,+++    testRegex "abcd" [caseless]+        ["ABCD"]+        [Just ["ABCD"]]+    ,+++    testRegex "a(bc)d" [caseless]+        ["ABCD"]+        [Just ["ABCD", "BC"]]+    ,+++    testRegex "a[-]?c" [caseless]+        ["AC"]+        [Just ["AC"]]+    ,+++    testRegex "(abc)\\1" [caseless]+        ["ABCABC"]+        [Just ["ABCABC", "ABC"]]+    ,+++    testRegex "([a-c]*)\\1" [caseless]+        ["ABCABC"]+        [Just ["ABCABC", "ABC"]]+    ,++    testRegex "a(?!b)." []+        ["abad"]+        [Just ["ad"]]+    ,+++    testRegex "a(?=d)." []+        ["abad"]+        [Just ["ad"]]+    ,+++    testRegex "a(?=c|d)." []+        ["abad"]+        [Just ["ad"]]+    ,+++    testRegex "a(?:b|c|d)(.)" []+        ["ace"]+        [Just ["ace", "e"]]+    ,+++    testRegex "a(?:b|c|d)*(.)" []+        ["ace"]+        [Just ["ace", "e"]]+    ,+++    testRegex "a(?:b|c|d)+?(.)" []+        ["ace",+         "acdbcdbe"]+        [Just ["ace", "e"],+         Just ["acd", "d"]]+    ,+++    testRegex "a(?:b|c|d)+(.)" []+        ["acdbcdbe"]+        [Just ["acdbcdbe", "e"]]+    ,+++    testRegex "a(?:b|c|d){2}(.)" []+        ["acdbcdbe"]+        [Just ["acdb", "b"]]+    ,+++    testRegex "a(?:b|c|d){4,5}(.)" []+        ["acdbcdbe"]+        [Just ["acdbcdb", "b"]]+    ,+++    testRegex "a(?:b|c|d){4,5}?(.)" []+        ["acdbcdbe"]+        [Just ["acdbcd", "d"]]+    ,+++    testRegex "((foo)|(bar))*" []+        ["foobar"]+        [Just ["foobar", "bar", "foo", "bar"]]+    ,+++    testRegex "a(?:b|c|d){6,7}(.)" []+        ["acdbcdbe"]+        [Just ["acdbcdbe", "e"]]+    ,+++    testRegex "a(?:b|c|d){6,7}?(.)" []+        ["acdbcdbe"]+        [Just ["acdbcdbe", "e"]]+    ,+++    testRegex "a(?:b|c|d){5,6}(.)" []+        ["acdbcdbe"]+        [Just ["acdbcdbe", "e"]]+    ,+++    testRegex "a(?:b|c|d){5,6}?(.)" []+        ["acdbcdbe"]+        [Just ["acdbcdb", "b"]]+    ,+++    testRegex "a(?:b|c|d){5,7}(.)" []+        ["acdbcdbe"]+        [Just ["acdbcdbe", "e"]]+    ,+++    testRegex "a(?:b|c|d){5,7}?(.)" []+        ["acdbcdbe"]+        [Just ["acdbcdb", "b"]]+    ,+++    testRegex "a(?:b|(c|e){1,2}?|d)+?(.)" []+        ["ace"]+        [Just ["ace", "c", "e"]]+    ,+++    testRegex "^(.+)?B" []+        ["AB"]+        [Just ["AB", "A"]]+    ,+++    testRegex "^([^a-z])|(\\^)$" []+        ["."]+        [Just [".", "."]]+    ,++    testRegex "^[<>]&" []+        ["<&OUT"]+        [Just ["<&"]]+    ,+++    testRegex "^(a\\1?){4}$" []+        ["aaaaaaaaaa",+         "*** Failers",+         "AB",+         "aaaaaaaaa",+         "aaaaaaaaaaa"]+        [Just ["aaaaaaaaaa", "aaaa"],+         Nothing,+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "^(a(?(1)\\1)){4}$" []+        ["aaaaaaaaaa",+         "*** Failers",+         "aaaaaaaaa",+         "aaaaaaaaaaa"]+        [Just ["aaaaaaaaaa", "aaaa"],+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "(?:(f)(o)(o)|(b)(a)(r))*" []+        ["foobar"]+        [Just ["foobar", "f", "o", "o", "b", "a", "r"]]+    ,+++    testRegex "(?<=a)b" []+        ["ab",+         "*** Failers",+         "cb",+         "b"]+        [Just ["b"],+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "(?<!c)b" []+        ["ab",+         "b",+         "b"]+        [Just ["b"],+         Just ["b"],+         Just ["b"]]+    ,+++    testRegex "(?:..)*a" []+        ["aba"]+        [Just ["aba"]]+    ,+++    testRegex "(?:..)*?a" []+        ["aba"]+        [Just ["a"]]+    ,+++    testRegex "^(?:b|a(?=(.)))*\\1" []+        ["abc"]+        [Just ["ab", "b"]]+    ,+++    testRegex "^(){3,5}" []+        ["abc"]+        [Just ["", ""]]+    ,+++    testRegex "^(a+)*ax" []+        ["aax"]+        [Just ["aax", "a"]]+    ,+++    testRegex "^((a|b)+)*ax" []+        ["aax"]+        [Just ["aax", "a", "a"]]+    ,+++    testRegex "^((a|bc)+)*ax" []+        ["aax"]+        [Just ["aax", "a", "a"]]+    ,+++    testRegex "(a|x)*ab" []+        ["cab"]+        [Just ["ab"]]+    ,+++    testRegex "(a)*ab" []+        ["cab"]+        [Just ["ab"]]+    ,+++    testRegex "(?:(?i)a)b" []+        ["ab"]+        [Just ["ab"]]+    ,+++    testRegex "((?i)a)b" []+        ["ab"]+        [Just ["ab", "a"]]+    ,+++    testRegex "(?:(?i)a)b" []+        ["Ab"]+        [Just ["Ab"]]+    ,+++    testRegex "((?i)a)b" []+        ["Ab"]+        [Just ["Ab", "A"]]+    ,+++    testRegex "(?:(?i)a)b" []+        ["*** Failers",+         "cb",+         "aB"]+        [Nothing,+         Nothing,+         Nothing]+    ,+    testRegex "((?i)a)b" []+        []+        []+    ,+++    testRegex "(?i:a)b" []+        ["ab"]+        [Just ["ab"]]+    ,+++    testRegex "((?i:a))b" []+        ["ab"]+        [Just ["ab", "a"]]+    ,+++    testRegex "(?i:a)b" []+        ["Ab"]+        [Just ["Ab"]]+    ,+++    testRegex "((?i:a))b" []+        ["Ab"]+        [Just ["Ab", "A"]]+    ,+++    testRegex "(?i:a)b" []+        ["*** Failers",+         "aB",+         "aB"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "((?i:a))b" []+        []+        []+    ,+++    testRegex "(?:(?-i)a)b" [caseless]+        ["ab"]+        [Just ["ab"]]+    ,+++    testRegex "((?-i)a)b" [caseless]+        ["ab"]+        [Just ["ab", "a"]]+    ,+++    testRegex "(?:(?-i)a)b" [caseless]+        ["aB"]+        [Just ["aB"]]+    ,+++    testRegex "((?-i)a)b" [caseless]+        ["aB"]+        [Just ["aB", "a"]]+    ,+++    testRegex "(?:(?-i)a)b" [caseless]+        ["*** Failers",+         "aB",+         "Ab"]+        [Nothing,+         Just ["aB"],+         Nothing]+    ,+++    testRegex "((?-i)a)b" [caseless]+        []+        []+    ,+++    testRegex "(?:(?-i)a)b" [caseless]+        ["aB"]+        [Just ["aB"]]+    ,+++    testRegex "((?-i)a)b" [caseless]+        ["aB"]+        [Just ["aB", "a"]]+    ,+++    testRegex "(?:(?-i)a)b" [caseless]+        ["*** Failers",+         "Ab",+         "AB"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "((?-i)a)b" [caseless]+        []+        []+    ,+++    testRegex "(?-i:a)b" [caseless]+        ["ab"]+        [Just ["ab"]]+    ,+++    testRegex "((?-i:a))b" [caseless]+        ["ab"]+        [Just ["ab", "a"]]+    ,+++    testRegex "(?-i:a)b" [caseless]+        ["aB"]+        [Just ["aB"]]+    ,+++    testRegex "((?-i:a))b" [caseless]+        ["aB"]+        [Just ["aB", "a"]]+    ,+++    testRegex "(?-i:a)b" [caseless]+        ["*** Failers",+         "AB",+         "Ab"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "((?-i:a))b" [caseless]+        []+        []+    ,+++    testRegex "(?-i:a)b" [caseless]+        ["aB"]+        [Just ["aB"]]+    ,+++    testRegex "((?-i:a))b" [caseless]+        ["aB"]+        [Just ["aB", "a"]]+    ,+++    testRegex "(?-i:a)b" [caseless]+        ["*** Failers",+         "Ab",+         "AB"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "((?-i:a))b" [caseless]+        []+        []+    ,+++    testRegex "((?-i:a.))b" [caseless]+        ["*** Failers",+         "AB",+         "a\nB"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "((?s-i:a.))b" [caseless]+        ["a\nB"]+        [Just ["a\nB", "a\n"]]+    ,+++    testRegex "(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))" []+        ["cabbbb"]+        [Just ["cabbbb"]]+    ,++    testRegex "(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))" []+        ["caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"]+        [Just ["caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"]]+    ,+++    testRegex "(ab)\\d\\1" [caseless]+        ["Ab4ab",+         "ab4Ab"]+        [Just ["Ab4ab", "Ab"],+         Just ["ab4Ab", "ab"]]+    ,+++    testRegex "foo\\w*\\d{4}baz" []+        ["foobar1234baz"]+        [Just ["foobar1234baz"]]+    ,+++    testRegex "x(~~)*(?:(?:F)?)?" []+        ["x~~"]+        [Just ["x~~", "~~"]]+    ,+++    testRegex "^a(?#xxx){3}c" []+        ["aaac"]+        [Just ["aaac"]]+    ,+++    testRegex "^a (?#xxx) (?#yyy) {3}c" [extended]+        ["aaac"]+        [Just ["aaac"]]+    ,+++    testRegex "(?<![cd])b" []+        ["*** Failers",+         "B\nB",+         "dbcb"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "(?<![cd])[ab]" []+        ["dbaacb"]+        [Just ["a"]]+    ,+++    testRegex "(?<!(c|d))b" []+        []+        []+    ,+++    testRegex "(?<!(c|d))[ab]" []+        ["dbaacb"]+        [Just ["a"]]+    ,+++    testRegex "(?<!cd)[ab]" []+        ["cdaccb"]+        [Just ["b"]]+    ,++{-+    testRegex "^(?:a?b?)*$" []+        ["a",+         "ab",+         "aaa   ",+         "*** Failers",+         "dbcb",+         "a--",+         "aa-- "]+        [Just ["a"],+         Just ["ab"],+         Just ["aaa"],+         Nothing,+         Nothing,+         Nothing,+         Nothing]+    ,+    -}+++    testRegex "((?s)^a(.))((?m)^b$)" []+        ["a\nb\nc\n"]+        [Just ["a\nb", "a\n", "\n", "b"]]+    ,+++    testRegex "((?m)^b$)" []+        ["a\nb\nc\n"]+        [Just ["b", "b"]]+    ,+++    testRegex "(?m)^b" []+        ["a\nb\n"]+        [Just ["b"]]+    ,+++    testRegex "(?m)^(b)" []+        ["a\nb\n"]+        [Just ["b", "b"]]+    ,+++    testRegex "((?m)^b)" []+        ["a\nb\n"]+        [Just ["b", "b"]]+    ,+++    testRegex "\\n((?m)^b)" []+        ["a\nb\n"]+        [Just ["\nb", "b"]]+    ,+++    testRegex "((?s).)c(?!.)" []+        ["a\nb\nc\n",+         "a\nb\nc\n"]+        [Just ["\nc", "\n"],+         Just ["\nc", "\n"]]+    ,+++    testRegex "((?s)b.)c(?!.)" []+        ["a\nb\nc\n",+         "a\nb\nc\n"]+        [Just ["b\nc", "b\n"],+         Just ["b\nc", "b\n"]]+    ,+++    testRegex "^b" []+        []+        []+    ,+++    testRegex "()^b" []+        ["*** Failers",+         "a\nb\nc\n",+         "a\nb\nc\n"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "((?m)^b)" []+        ["a\nb\nc\n"]+        [Just ["b", "b"]]+    ,++{-+    testRegex "(?(1)a|b)" []+        []+        []+    ,+++    testRegex "(?(1)b|a)" []+        ["a"]+        [Just ["a"]]+    ,++-}++    testRegex "(x)?(?(1)a|b)" []+        ["*** Failers",+         "a",+         "a"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "(x)?(?(1)b|a)" []+        ["a"]+        [Just ["a"]]+    ,+++    testRegex "()?(?(1)b|a)" []+        ["a"]+        [Just ["a"]]+    ,+++    testRegex "()(?(1)b|a)" []+        []+        []+    ,+++    testRegex "()?(?(1)a|b)" []+        ["a"]+        [Just ["a", ""]]+    ,+++    testRegex "^(\\()?blah(?(1)(\\)))$" []+        ["(blah)",+         "blah",+         "a",+         "blah)",+         "(blah"]+        [Just ["(blah)", "(", ")"],+         Just ["blah"],+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "^(\\(+)?blah(?(1)(\\)))$" []+        ["(blah)",+         "blah",+         "*** Failers",+         "blah)",+         "(blah"]+        [Just ["(blah)", "(", ")"],+         Just ["blah"],+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "(?(?!a)a|b)" []+        []+        []+    ,+++    testRegex "(?(?!a)b|a)" []+        ["a"]+        [Just ["a"]]+    ,+++    testRegex "(?(?=a)b|a)" []+        ["*** Failers",+         "a",+         "a"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "(?(?=a)a|b)" []+        ["a"]+        [Just ["a"]]+    ,+++    testRegex "(?=(a+?))(\\1ab)" []+        ["aaab"]+        [Just ["aab", "a", "aab"]]+    ,+++    testRegex "^(?=(a+?))\\1ab" []+        []+        []+    ,+++    testRegex "(\\w+:)+" []+        ["one:"]+        [Just ["one:", "one:"]]+    ,+++    testRegex "$(?<=^(a))" []+        ["a"]+        [Just ["", "a"]]+    ,+++    testRegex "(?=(a+?))(\\1ab)" []+        ["aaab"]+        [Just ["aab", "a", "aab"]]+    ,+++    testRegex "^(?=(a+?))\\1ab" []+        ["*** Failers",+         "aaab",+         "aaab"]+        [Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "([\\w:]+::)?(\\w+)$" []+        ["abcd",+         "xy:z:::abcd"]+        [Just ["abcd", "", "abcd"],+         Just ["xy:z:::abcd", "xy:z:::", "abcd"]]+    ,+++    testRegex "^[^bcd]*(c+)" []+        ["aexycd"]+        [Just ["aexyc", "c"]]+    ,+++    testRegex "(a*)b+" []+        ["caab"]+        [Just ["aab", "aa"]]+    ,+++    testRegex "([\\w:]+::)?(\\w+)$" []+        ["abcd",+         "xy:z:::abcd",+         "*** Failers",+         "abcd:",+         "abcd:"]+        [Just ["abcd", "", "abcd"],+         Just ["xy:z:::abcd", "xy:z:::", "abcd"],+         Just ["Failers", "", "Failers"],+         Nothing,+         Nothing]+    ,+++    testRegex "^[^bcd]*(c+)" []+        ["aexycd"]+        [Just ["aexyc", "c"]]+    ,+++    testRegex "(>a+)ab" []+        []+        []+    ,+++    testRegex "(?>a+)b" []+        ["aaab"]+        [Just ["aaab"]]+    ,+++    testRegex "([[:]+)" []+        ["a:[b]:"]+        [Just [":[", ":["]]++    ,+    testRegex "([[=]+)" []+        ["a=[b]="]+        [Just ["=[", "=["]]+    ,+++    testRegex "([[.]+)" []+        ["a.[b]."]+        [Just [".[", ".["]]+    ,+++    testRegex "((?>a+)b)" []+        ["aaab"]+        [Just ["aaab", "aaab"]]+    ,+++    testRegex "(?>(a+))b" []+        ["aaab"]+        [Just ["aaab", "aaa"]]+    ,+++    testRegex "((?>[^()]+)|\\([^()]*\\))+" []+        ["((abc(ade)ufh()()x"]+        [Just ["abc(ade)ufh()()x", "x"]]+    ,+++    testRegex "a\\Z" []+        ["aaab",+         "a\nb\n"]+        [Nothing,+         Nothing]+    ,+++    testRegex "b\\Z" []+        ["a\nb\n"]+        [Just ["b"]]+    ,+++    testRegex "b\\z" []+        []+        []+    ,+++    testRegex "b\\Z" []+        ["a\\nb"]+        [Just ["b"]]+    ,++    testRegex "(?>.*)(?<=(abcd|wxyz))" []+        ["alphabetabcd",+         "endingwxyz",+         "*** Failers",+         "a rather long string that doesn't end with one of them"]+        [Just ["alphabetabcd", "abcd"],+         Just ["endingwxyz", "wxyz"],+         Nothing,+         Nothing]+    ,+++    testRegex "word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword" []+        ["word cat dog elephant mussel cow horse canary baboon snake shark otherword",+         "word cat dog elephant mussel cow horse canary baboon snake shark"+         ]+        [Just ["word cat dog elephant mussel cow horse canary baboon snake shark otherword"],+         Nothing]+    ,++    testRegex "((Z)+|A)*" []+        ["ZABCDEFG"]+        [Just ["ZA", "A", "Z"]]+    ,+++    testRegex "(Z()|A)*" []+        ["ZABCDEFG"]+        [Just ["ZA", "A", ""]]+    ,+++    testRegex "(Z(())|A)*" []+        ["ZABCDEFG"]+        [Just ["ZA", "A", "", ""]]+    ,++    testRegex "((?>Z)+|A)*" []+        ["ZABCDEFG"]+        [Just ["ZA", "A"]]+    ,+++    testRegex "((?>)+|A)*" []+        ["ZABCDEFG"]+        [Just ["", ""]]+    ,++    testRegex "\\Qabc\\$xyz\\E" []+        ["abc\\$xyz"]+        [Just ["abc\\$xyz"]]+    ,+    testRegex "\\Qabc\\E\\$\\Qxyz\\E" []+        ["abc$xyz"]+        [Just ["abc$xyz"]]+    ,+    testRegex "\\Gabc" []+        ["abc",+         "*** Failers",+         "xyzabc  "]+        [Just ["abc"],+         Nothing,+         Nothing]+    ,++    testRegex "a(?x: b c )d" []+        ["XabcdY",+         "*** Failers ",+         "Xa b c d Y "]+        [Just ["abcd"],+         Nothing,+         Nothing]+    ,+++    testRegex "((?x)x y z | a b c)" []+        ["XabcY",+         "AxyzB "]+        [Just ["abc", "abc"],+         Just ["xyz", "xyz"]]+    ,+++    testRegex "(?i)AB(?-i)C" []+        ["XabCY",+         "*** Failers",+         "XabcY  "]+        [Just ["abC"],+         Nothing,+         Nothing]+    ,+++    testRegex "((?i)AB(?-i)C|D)E" []+        ["abCE",+         "DE",+         "*** Failers",+         "abcE",+         "abCe  ",+         "dE",+         "De    "]+        [Just ["abCE", "abC"],+         Just ["DE", "D"],+         Nothing,+         Nothing,+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "(.*)\\d+\\1" []+        ["abc123abc",+         "abc123bc "]+        [Just ["abc123abc", "abc"],+         Just ["bc123bc", "bc"]]+    ,++    testRegex "[z\\Qa-d]\\E]" []+        ["z",+         "a",+         "-",+         "d",+         "] ",+         "*** Failers",+         "b     "]+        [Just ["z"],+         Just ["a"],+         Just ["-"],+         Just ["d"],+         Just ["]"],+         Just ["a"],+         Nothing]++    , testRegex "(?<=Z)X." []+        ["\\x84XAZXB"]+        [Just ["XB"]]+    ,++    testRegex "ab cd (?x) de fg" []+        ["ab cd defg"]+        [Just ["ab cd defg"]]+    ,+++    testRegex "ab cd(?x) de fg" []+        ["ab cddefg",+         "** Failers ",+         "abcddefg"]+        [Just ["ab cddefg"],+         Nothing,+         Nothing]+    ,+++    testRegex "(?<![^f]oo)(bar)" []+        ["foobarX ",+         "** Failers ",+         "boobarX"]+        [Just ["bar", "bar"],+         Nothing,+         Nothing]+    ,+++    testRegex "(?<![^f])X" []+        ["offX",+         "** Failers",+         "onyX  "]+        [Just ["X"],+         Nothing,+         Nothing]+    ,+++    testRegex "(?<=[^f])X" []+        ["onyX",+         "** Failers",+         "offX "]+        [Just ["X"],+         Nothing,+         Nothing]+    ,++++    testRegex "(?:(?(1)a|b)(X))+" []+        ["bXaX"]+        [Just ["bXaX", "X"]]+    ,++    testRegex "(?:(?(1)\\1a|b)(X|Y))+" []+        ["bXXaYYaY",+         "bXYaXXaX  "]+        [Just ["bXXaYYaY", "Y"],+         Just ["bX", "X"]]+    ,+++    testRegex "()()()()()()()()()(?:(?(10)\\10a|b)(X|Y))+" []+        ["bXXaYYaY"]+        [Just ["bX", "", "", "", "", "", "", "", "", "", "X"]]+    ,+++    testRegex "[[,abc,]+]" []+        ["abc]",+         "a,b]",+         "[a,b,c]  "]+        [Just ["abc]"],+         Just ["a,b]"],+         Just ["[a,b,c]"]]+    ,+++++    testRegex "a*b*\\w" []+        ["aaabbbb",+         "aaaa",+         "a"]+        [Just ["aaabbbb"],+         Just ["aaaa"],+         Just ["a"]]+    ,+++    testRegex "a*b?\\w" []+        ["aaabbbb",+         "aaaa",+         "a"]+        [Just ["aaabb"],+         Just ["aaaa"],+         Just ["a"]]+    ,+++    testRegex "a*b{0,4}\\w" []+        ["aaabbbb",+         "aaaa",+         "a"]+        [Just ["aaabbbb"],+         Just ["aaaa"],+         Just ["a"]]+    ,+++    testRegex "(?=(\\w+))\\1:" []+        ["abcd:"]+        [Just ["abcd:", "abcd"]]+    ,+++    testRegex "^(?=(\\w+))\\1:" []+        ["abcd:"]+        [Just ["abcd:", "abcd"]]+    ,++++    testRegex "^[a\\E\\E-\\Ec]" []+        ["b",+         "** Failers",+         "-",+         "E    "]+        [Just ["b"],+         Nothing,+         Nothing,+         Nothing]+    ,+++    testRegex "(a){0,3}(?(1)b|(c|))*D" []+        ["abbD",+         "ccccD",+         "D  "]+        [Just ["abbD", "a"],+         Just ["ccccD", "", ""],+         Just ["D", "", ""]]+    ,+++    -- WARNING: at around this point, the file starts segfaulting ghci....+    testRegex "(a|)*\\d" []+        ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",+         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4"]+        [Nothing,+         Just ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4", ""]]++    ,+    testRegex "(?>a|)*\\d" []+        ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",+         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4"]+        [Nothing,+         Just ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4"]]++    ,++    testRegex "(?=(\\w+))\\1:" []+        ["abcd:"]+        [Just ["abcd:", "abcd"]]+    ,+++    testRegex "^(?=(\\w+))\\1:" []+        ["abcd:"]+        [Just ["abcd:", "abcd"]]+    ,++++    testRegex "^[a\\E\\E-\\Ec]" []+        ["b",+         "** Failers",+         "-",+         "E    "]+        [Just ["b"],+         Nothing,+         Nothing,+         Nothing]+    ,++++++++    testRegex "(a){0,3}(?(1)b|(c|))*D" []+        ["abbD",+         "ccccD",+         "D  "]+        [Just ["abbD", "a"],+         Just ["ccccD", "", ""],+         Just ["D", "", ""]]+    ,+++    testRegex "(a|)*\\d" []+        ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",+         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4"]+        [Nothing,+         Just ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4", ""]]+    ,+++    testRegex "(?>a|)*\\d" []+        ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",+         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4"]+        [Nothing,+         Just ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4"]]+    ,++    testRegex "( (A | (?(1)0|) )*   )" [extended]+        ["abcd"]+        [Just ["", "", ""]]++    ,+    testRegex "^[\\w]+" []+        ["*** Failers",+         "\201cole"]+        [Nothing,+         Nothing]++++    ,+    testRegex "^[\\w]+" []+        ["*** Failers",+         "\201cole"]+        [Nothing,+         Nothing]++{-+    ,++    testRegex "(a.b(?s)c.d|x.y)p.q" []+        ["a+bc+dp+q",+         "a+bc\ndp+q",+         "x\nyp+q ",+         "a\nbc\ndp+q",+         "a+bc\ndp\nq",+         "x\nyp\nq "+         ]+        [Just ["a+bc+dp+q"],+         Just ["a+bc\ndp+q"],+         Just ["x\nyp+q"],+         Nothing,+         Nothing,+         Nothing+         ]+         -}++    ,+    testRegex "a\\d\\z" []+        ["ba0",+         "*** Failers",+         "ba0\n",+         "ba0\ncd   "]+        [Just ["a0"],+         Nothing,+         Nothing,+         Nothing]++    ,+    testRegex "a\\d\\Z" []+        ["ba0",+         "ba0\n",+         "ba0\ncd   "]+        [Just ["a0"],+         Just ["a0"],+         Nothing]++    ,+    testRegex "a\\d$" []+        ["ba0",+         "ba0\n",+         "*** Failers",+         "ba0\ncd   "]+        [Just ["a0"],+         Just ["a0"],+         Nothing,+         Nothing]+    ,+    testRegex "a+" []+        ["aaaa"]+        [Just ["aaaa"]]++++    ,+    testRegex "^\\d{2,3}X" []+        ["12X",+         "123X",+         "*** Failers",+         "X",+         "1X",+         "1234X     "]+        [Just ["12X"],+         Just ["123X"],+         Nothing,+         Nothing,+         Nothing,+         Nothing]+++    ,+    testRegex "^[abcd]\\d" []+        ["a45",+         "b93",+         "c99z",+         "d04",+         "*** Failers",+         "e45",+         "abcd      ",+         "abcd1234",+         "1234  "]+        [Just ["a4"],+         Just ["b9"],+         Just ["c9"],+         Just ["d0"],+         Nothing,+         Nothing,+         Nothing,+         Nothing,+         Nothing]+++{-+    ,+    testRegex "^(a*\\w|ab)=(a*\\w|ab)" []+        ["ab=ab"]+        [Just ["ab=ab", "ab"]]+        -}+++    ,+    testRegex "^(a*\\w|ab)=(?1)" []+        ["ab=ab"]+        [Just ["ab=ab", "ab"]]+++{-+    ,+    testRegex "^([^()]|\\((?1)*\\))*$" []+        ["abc",+         "a(b)c",+         "a(b(c))d  ",+         "*** Failers)",+         "a(b(c)d  "]+        [Just ["abc"],+         Just ["a(b)c"],+         Just ["a(b(c))d"],+         Nothing,+         Nothing]++    ,+    testRegex "^>abc>([^()]|\\((?1)*\\))*<xyz<$" []+        [">abc>123<xyz<",+         ">abc>1(2)3<xyz<",+         ">abc>(1(2)3)<xyz<"]+        [Just [">abc>123<xyz<"],+         Just [">abc>1(2)3<xyz<"],+         Just [">abc>(1(2)3)<xyz<"]]++-}++    ,+    testRegex "^(?>a*)\\d" []+        ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876",+         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]+        [Just ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9"],+         Nothing]++++++    ,+    testRegex "(?<=abc|xy)123" []+        ["abc12345",+         "wxy123z",+         "*** Failers",+         "123abc"]+        [Just ["123"],+         Just ["123"],+         Nothing,+         Nothing]+++    ,+    testRegex "(?<!abc|xy)123" []+        ["123abc",+         "mno123456 ",+         "*** Failers",+         "abc12345",+         "wxy123z"]+        [Just ["123"],+         Just ["123"],+         Nothing,+         Nothing,+         Nothing]++    ,+    testRegex "abc(?C1)xyz" []+        ["abcxyz",+         "123abcxyz999 "]+        [ Just ["abcxyz"],+         Just ["abcxyz"]]++++++{-+    ,+    testRegex "\\Gabc" []+        ["abcdef",+         "defabcxyz\\>3 ",+         "defabcxyz"]+        [Just ["abc"],+         Just ["abc"],+         Nothing]+         -}++    ,++    testRegex "[\\xFF]" []+        [">\xff<"]+        [Just ["\xff"]]++    ,+    testRegex "[^\\xFF]" []+        ["XYZ"]+        [Just ["X"]]+++    ,+    testRegex "^\\pN{2,3}X" []+        ["12X",+         "123X",+         "*** Failers",+         "X",+         "1X",+         "1234X     "]+        [Just ["12X"],+         Just ["123X"],+         Nothing,+         Nothing,+         Nothing,+         Nothing]++    -- named capture group tests+    , -- Handles cases with no capture groups+    testCaptures 0 "no capture groups" []++    , -- Properly labels capture groups+    testCaptures 1 "(?<first>first capture group)" [("first", 0)]++    , -- Doesn't return labels for unnamed groups+    testCaptures 1 "(doesn't return unnamed groups)" []++    , -- Counts but doesn't return unnamed groups+    testCaptures 3 "(?<one>abc) (def) (?<three>ghi)" [("one", 0), ("three", 2)]++    , -- Doesn't count non-capturing groups+    testCaptures 1 "(?:abc) (?<named>def)" [("named", 0)]++    , -- Doesn't count named back-references+    testCaptures 2 "(?<first>abc) (?P=first) (?<second>def)" [("first", 0), ("second", 1)]++    , -- Test alternate group naming syntaxes+    testCaptures 3 "(?'first'abc) (?P<second>def) (?<third>ghi)" [("first", 0), ("second", 1), ("third", 2)]++    , -- Groups are returned in numeric order+    testCaptures 3 "(?'c'0) (?P<b>1) (?<a>2)" [("c", 0), ("b", 1), ("a", 2)]++    , -- Handles alternation between groups+    testCaptures 2 "(?<optionA>abc)|(?<optionB>def)" [("optionA", 0), ("optionB", 1)]++    , -- Labels optional groups+    testCaptures 2 "(?<named>abc)(?<optional>def)?" [("named", 0), ("optional", 1)]++    , -- Handles nested named groups+    testCaptures 3 "(?<named>a(?<nested>b)c) (?<unnested>d)" [("named", 0), ("nested", 1), ("unnested", 2)]++    , testLabel "compile failure on duplicate named groups" $+            TestCase $ (assertEqual' "compile failure on duplicate named groups"+                         (Left ("two named subpatterns have the same name"))+                         (compileM "(?<dup>abc) (?<dup>def)" []))++ ]