diff --git a/Data/Text/ICU/Regex.hs b/Data/Text/ICU/Regex.hs
--- a/Data/Text/ICU/Regex.hs
+++ b/Data/Text/ICU/Regex.hs
@@ -90,18 +90,14 @@
   withForeignPtr reRe $ \rePtr ->
     withForeignPtr hayfp $ \hayPtr -> handleError $
       uregex_setText rePtr hayPtr (fromIntegral hayLen)
-  writeIORef reText hayfp
+  writeIORef reText $! H hayfp hayLen
 
 -- | Get the subject text that is currently associated with this
 -- regular expression object.
 getText :: Regex -> IO (ForeignPtr Word16, I16)
-getText Regex{..} =
-  alloca $ \lenPtr -> do
-    _ <- withForeignPtr reRe $ \rePtr -> handleError $
-         uregex_getText rePtr lenPtr
-    len <- peek lenPtr
-    fp <- readIORef reText
-    return (fp, fromIntegral len)
+getText Regex{..} = do
+  H fp len <- readIORef reText
+  return (fp, len)
 
 -- | Return the source form of the pattern used to construct this
 -- regular expression or match.
@@ -153,7 +149,7 @@
 {-# INLINE clone #-}
 clone Regex{..} = do
   fp <- newForeignPtr uregex_close =<< withForeignPtr reRe (handleError . uregex_clone)
-  Regex fp `fmap` newIORef emptyForeignPtr
+  Regex fp `fmap` newIORef (H emptyForeignPtr 0)
 
 -- | Return the number of capturing groups in this regular
 -- expression's pattern.
diff --git a/Data/Text/ICU/Regex/Internal.hsc b/Data/Text/ICU/Regex/Internal.hsc
--- a/Data/Text/ICU/Regex/Internal.hsc
+++ b/Data/Text/ICU/Regex/Internal.hsc
@@ -22,6 +22,7 @@
     (
     -- * Types
       MatchOption(..)
+    , Haystack(..)
     , Regex(..)
     , URegularExpression
     -- * Functions
@@ -52,7 +53,7 @@
                                      handleError, handleParseError)
 import Data.Typeable (Typeable)
 import Data.Word (Word16, Word32)
-import Foreign.ForeignPtr (ForeignPtr, newForeignPtr, touchForeignPtr)
+import Foreign.ForeignPtr (ForeignPtr, newForeignPtr, touchForeignPtr, withForeignPtr)
 import Foreign.Ptr (FunPtr, Ptr)
 import Prelude hiding (catch)
 import System.IO.Unsafe (unsafePerformIO)
@@ -126,6 +127,8 @@
     -- process.  A limit is enabled by default.
       deriving (Eq, Show, Typeable)
 
+data Haystack = H (ForeignPtr Word16) {-# UNPACK #-} !T.I16
+
 -- | A compiled regular expression.
 --
 -- 'Regex' values are usually constructed using the 'regex' or
@@ -135,7 +138,7 @@
 -- quotes (though this does not allow you to specify any 'Option's).
 data Regex = Regex {
       reRe :: ForeignPtr URegularExpression
-    , reText :: IORef (ForeignPtr Word16)
+    , reText :: IORef Haystack
     }
 
 emptyForeignPtr :: ForeignPtr Word16
@@ -144,18 +147,24 @@
 
 -- | Compile a regular expression with the given options.  This
 -- function throws a 'ParseError' if the pattern is invalid.
+--
+-- The 'Regex' is initialized with empty text to search against.
 regex :: [MatchOption] -> Text -> IO Regex
 regex opts pat = T.useAsPtr pat $ \pptr plen -> do
   let (flags,workLimit,stackLimit) = toURegexpOpts opts
   ptr <- handleParseError isRegexError $
          uregex_open pptr (fromIntegral plen) flags
-  fp <- newForeignPtr uregex_close ptr
-  when (workLimit /= -1) .
+  refp <- newForeignPtr uregex_close ptr
+  (hayfp, hayLen) <- T.asForeignPtr T.empty
+  withForeignPtr refp $ \rePtr ->
+    withForeignPtr hayfp $ \hayPtr -> handleError $
+      uregex_setText rePtr hayPtr (fromIntegral hayLen)
+  when (workLimit > -1) .
     handleError $ uregex_setTimeLimit ptr (fromIntegral workLimit)
-  when (stackLimit /= -1) .
+  when (stackLimit > -1) .
     handleError $ uregex_setStackLimit ptr (fromIntegral stackLimit)
-  touchForeignPtr fp
-  Regex fp `fmap` newIORef emptyForeignPtr
+  touchForeignPtr refp
+  Regex refp `fmap` newIORef (H hayfp 0)
 
 data URegularExpression
 
diff --git a/Data/Text/ICU/Regex/Pure.hs b/Data/Text/ICU/Regex/Pure.hs
--- a/Data/Text/ICU/Regex/Pure.hs
+++ b/Data/Text/ICU/Regex/Pure.hs
@@ -137,9 +137,11 @@
 findAll :: Regex -> Text -> [Match]
 findAll re0 haystack = unsafePerformIO . unsafeInterleaveIO $ go 0
   where
-    go !n = matching re0 haystack $ \re -> do
-      f <- IO.find re n
-      if f
+    len = fromIntegral . T.lengthWord16 $ haystack
+    go !n | n >= len  = return []
+          | otherwise = matching re0 haystack $ \re -> do
+      found <- IO.find re n
+      if found
         then do
           n' <- IO.end_ re 0
           (Match re n:) `fmap` go n'
@@ -161,6 +163,7 @@
 -- expression or match's pattern.
 groupCount :: Regular r => r -> Int
 groupCount = unsafePerformIO . IO.groupCount . regRe
+{-# INLINE groupCount #-}
 
 -- | A combinator for returning a list of all capturing groups on a
 -- 'Match'.
@@ -213,6 +216,6 @@
 grouping n (Match m _) act = unsafePerformIO $ do
   count <- IO.groupCount m
   let n' = fromIntegral n
-  if n < 0 || (n' >= count && count > 0)
-    then return Nothing
-    else Just `fmap` act m
+  if n' == 0 || (n' >= 0 && n' < count)
+    then Just `fmap` act m
+    else return Nothing
diff --git a/text-icu.cabal b/text-icu.cabal
--- a/text-icu.cabal
+++ b/text-icu.cabal
@@ -1,5 +1,5 @@
 name:           text-icu
-version:        0.6.3.1
+version:        0.6.3.2
 synopsis:       Bindings to the ICU library
 homepage:       http://bitbucket.org/bos/text-icu
 bug-reports:    http://bitbucket.org/bos/text-icu/issues
