diff --git a/Text/Regex/Less.hs b/Text/Regex/Less.hs
--- a/Text/Regex/Less.hs
+++ b/Text/Regex/Less.hs
@@ -1,46 +1,82 @@
 {- copyright (c) sreservoir.
    license bsd three-clause. -}
 
-module Text.Regex.Less ((=~),(<<),truth,subs,derefs,bref) where
+module Text.Regex.Less
+  ( (=~),(<<),
+    truth,subs,subg,derefs,bref,matchN)
+  where
 
 import qualified Text.Regex.PCRE as R
-import qualified Data.Array as A
+import qualified Data.Array.IArray as A
 import Text.Regex.Less.Quackers
 
-type Result = (String,[R.MatchArray])
+type Match = (String,[R.MatchArray])
 
 -- standard usage:
-  --  "" =~ ""
-  --  "" =~ "" << RECtOpts
-  --  "" =~ "" << RERtOpts
-  --  "" =~ "" << RECtOpts << RERtOpts
--- value suitable for use below.
+--   "" =~ ""
+--   "" =~ "" << [RECtOpts]
+--   "" =~ "" << [RERtOpts]
+--   "" =~ "" << [RECtOpts] << RERtOpts
+-- value is suitable for use below.
 infixl 4 =~
-(=~) :: QLR a => String -> a -> Result
-a =~ b = a << R.matchAll (compile b) a
+(=~) :: QLR a => String -> a -> Match
+a =~ b = a << execute b a
 
+-- (a << b) = (a,b)
 infixl 5 <<
 (<<) :: a -> b -> (a,b)
 a << b = (a,b)
 
-truth :: Result -> Bool
+-- whether the match succeeded.
+truth :: Match -> Bool
 truth (_,a) = not (null a)
 
-subs :: Result -> String -> String
-subs a b = s ++ derefs a b ++ f
+-- replaces matched substring with supplied string.
+-- supplied string is passed through derefs first.
+subs :: Match -> String -> String
+subs a b = s ++ derefs (bref a) b ++ f
   where o = fst a
         (i,c) = head (snd a) A.! 0
         (s,r) = splitAt i o
         f = drop c r
 
-derefs :: Result -> String -> String
-derefs a ('^':'^':bs) = '^' : derefs a bs
-derefs a ('^':bs)     =
+-- as subs, to every match.
+subg :: Match -> String -> String
+subg a b = subg' o (decay (map A.elems m)) b
+  where (o,m) = a
+
+-- for each match part, does just what it needs.
+-- if there are more, repeat with the rest.
+subg' :: String -> [[(Int,Int)]] -> String -> String
+subg' ors (cur@((ini,chs):_):ms) sub =
+  take ini ors ++ derefs bref' sub
+      ++ subg' (drop (ini + chs) ors) ms sub
+    where bref' a = R.extract (cur !! a) ors
+subg' _ _ _ = []
+
+-- reduces offset by number used by the previous.
+decay :: [[(Int,Int)]] -> [[(Int,Int)]]
+decay (x:xs) = x : decay rest
+  where rest = map (map proc) xs
+        proc (a,b) = a - uncurry (+) (head x) << b
+decay [] = []
+        
+-- does backreferences with ` .
+derefs :: (Int -> String) -> String -> String
+derefs f ('`':'`':bs) = '`' : derefs f bs
+derefs f ('`':'.':bs) = derefs f bs
+derefs f ('`':bs)     =
   case reads bs of
-    [(c,d)] -> bref a c ++ derefs a d
+    [(c,d)] -> f c ++ derefs f d
     _       -> undefined
-derefs a (b:bs)       = b : derefs a bs
+derefs f (b:bs)       = b : derefs f bs
 derefs _ []           = []
 
-bref :: Result -> Int -> String
+-- returns the indexed substring.
+-- backref 0 is the entire match.
+bref :: Match -> Int -> String
 bref a i = R.extract (head (snd a) A.! i) (fst a)
+
+-- takes one of the matches.
+matchN :: Match -> Int -> Match
+matchN (a,b) i = (a,[b !! i])
diff --git a/Text/Regex/Less/Quackers.hs b/Text/Regex/Less/Quackers.hs
--- a/Text/Regex/Less/Quackers.hs
+++ b/Text/Regex/Less/Quackers.hs
@@ -8,38 +8,35 @@
 import qualified Text.Regex.PCRE as R
 import Text.Regex.Less.REOpts
 
--- the QLR (QuacksLikeRegex) class:
-  -- compile
--- instances of QLR:
-  -- String
-  -- (String,[RECtOpts])
-  -- (String,[RERtOpts])
-  -- (String,([RECtOpts],[RERtOpts]))
-  -- (String,([RERtOpts],[RECtOpts]))
-  -- ((String,[RECtOpts]),[RERtOpts])
-  -- ((String,[RERtOpts]),[RECtOpts])
+bsR :: String -> String
+bsR ('`':'`':cs) = '`' : bsR cs
+bsR ('`':cs) = '\\' : bsR cs
+bsR ('\\':cs) = "\\\\" ++ bsR cs
+bsR (c:cs) = c : bsR cs
+bsR [] = []
 
--- QuacksLikeRegex: can =~ .
 class QLR a where
   compile :: a -> R.Regex
+  execute :: a -> String -> [R.MatchArray]
+  execute a b = R.matchAll (compile a) b
 
 instance QLR String where
-  compile a = R.makeRegexOpts (reCtOpts []) (reRtOpts []) a
+  compile a = R.makeRegexOpts (reCtOpts []) (reRtOpts []) (bsR a)
 
 instance QLR (String,[RECtOpts]) where
-  compile (a,b) = R.makeRegexOpts (reCtOpts b) (reRtOpts []) a
+  compile (a,b) = R.makeRegexOpts (reCtOpts b) (reRtOpts []) (bsR a)
 
 instance QLR (String,[RERtOpts]) where
-  compile (a,b) = R.makeRegexOpts (reCtOpts []) (reRtOpts b) a
+  compile (a,b) = R.makeRegexOpts (reCtOpts []) (reRtOpts b) (bsR a)
 
 instance QLR ((String,[RECtOpts]),[RERtOpts]) where
-  compile ((a,b),c) = R.makeRegexOpts (reCtOpts b) (reRtOpts c) a
+  compile ((a,b),c) = R.makeRegexOpts (reCtOpts b) (reRtOpts c) (bsR a)
 
 instance QLR ((String,[RERtOpts]),[RECtOpts]) where
-  compile ((a,b),c) = R.makeRegexOpts (reCtOpts c) (reRtOpts b) a
+  compile ((a,b),c) = R.makeRegexOpts (reCtOpts c) (reRtOpts b) (bsR a)
 
 instance QLR (String,([RECtOpts],[RERtOpts])) where
-  compile (a,(b,c)) = R.makeRegexOpts (reCtOpts b) (reRtOpts c) a
+  compile (a,(b,c)) = R.makeRegexOpts (reCtOpts b) (reRtOpts c) (bsR a)
 
 instance QLR (String,([RERtOpts],[RECtOpts])) where
-  compile (a,(b,c)) = R.makeRegexOpts (reCtOpts c) (reRtOpts b) a
+  compile (a,(b,c)) = R.makeRegexOpts (reCtOpts c) (reRtOpts b) (bsR a)
diff --git a/pcre-less.cabal b/pcre-less.cabal
--- a/pcre-less.cabal
+++ b/pcre-less.cabal
@@ -1,26 +1,28 @@
 name:                pcre-less
-version:             0.2.0
-synopsis:            Nicer interface to regex-pcre
+version:             0.2.1
+synopsis:            Nicer interface to regex-pcre.
 description:
-  Unfortunately, docs don't exist yet.
-homepage:            ~
+  Uses regex-pcre to provide substitution, backrefs.
+  Uses '`' over '\\' just to be idiosyncratic. (It's prettier.)
+  See the tests for more information.
+-- homepage:         ~
 license:             BSD3
--- The file containing the license text.
 license-file:        LICENSE
 author:              sreservoir
 maintainer:          sreservoir@gmail.com
 category:            Text
 build-type:          Simple
 cabal-version:       >= 1.2
+extra-source-files:  test/QC.hs, test/HU.hs
 
 library
   exposed-modules:
     Text.Regex.Less
     Text.Regex.Less.REOpts
+    Text.Regex.Less.Quackers
   other-modules:
     Text.Regex.Less.RECtOpts
     Text.Regex.Less.RERtOpts
-    Text.Regex.Less.Quackers
   build-depends: base >= 4 && < 5,regex-pcre >= 0.94,array >= 0.3
   extensions: FlexibleInstances,TypeSynonymInstances
   ghc-options: -Wall
diff --git a/test/HU.hs b/test/HU.hs
new file mode 100644
--- /dev/null
+++ b/test/HU.hs
@@ -0,0 +1,86 @@
+{- copyright (c) sreservoir.
+   licensed under mit (x11). -}
+
+module Main where
+
+import Text.Regex.Less
+import Data.List
+import Test.HUnit
+
+main :: IO ()
+main = mapM_ runTestTT tests
+
+tests :: [Test]
+tests = map TestList
+  [ tests0, tests1, tests2, tests3,
+    tests4, tests5, tests6, tests7 ]
+
+tests0 :: [Test]
+tests0 =
+  [ TestLabel "sanity" $
+      TestCase (assertEqual "" (a+a) (2*a))
+    | a <- [ 1,19 .. 963 ] :: [Int] ]
+
+alnums :: [Char]
+alnums = '_' : ['A'..'Z'] ++ ['a'..'z'] ++ ['0'..'9']
+
+tests1 :: [Test]
+tests1 =
+  [ TestLabel "alnum `w" $
+      TestCase (assertBool (show a ++ " not `w?")
+                  (truth ([a] =~ "`w")))
+    | a <- alnums ]
+
+tests2 :: [Test]
+tests2 =
+  [ TestLabel "alnum not `W" $
+      TestCase (assertBool (show a ++ " is `W?") 
+                  (not (truth ([a] =~ "`W"))))
+    | a <- alnums ]
+
+tests3 :: [Test]
+tests3 =
+  [ TestLabel "other `W" $
+      TestCase (assertBool (show a ++ " not `W?") 
+                  (truth ([a] =~ "`W")))
+    | a <- ['\0'..'\DEL'] \\ alnums ]
+
+tests4 :: [Test]
+tests4 =
+  [ TestLabel "other not `w" $
+      TestCase (assertBool (show a ++ " is `w?") 
+                  (not (truth ([a] =~ "`w"))))
+    | a <- ['\0'..'\DEL'] \\ alnums ]
+
+prints :: [Char]
+prints = [' '..'~']
+
+tests5 :: [Test]
+tests5 =
+  [ TestLabel "simple once-substitution" $
+      TestCase (assertEqual "doubling"
+                  (subs (a =~ ".*") "`0`0")
+                  (a ++ a))
+    | b <- prints, c <- prints, a <- [[b,c]] ]
+
+tests6 :: [Test]
+tests6 =
+  [ TestLabel "extracting numbers" $
+      TestCase (assertEqual "numbers"
+                  (read (bref (fst a =~ "`d*") 0))
+                  (snd a))
+    | b <- [ 1,1000 .. 100000 ] :: [Integer], a <- [(show b,b)] ]
+
+tests7 :: [Test]
+tests7 =
+  [ TestLabel "testing primes :P" $
+      TestCase (assertEqual "primes"
+                  (snd a)
+                  (truth (replicate (fst a) '1' =~ "^1?$|^(11+?)`1+$")))
+    | a <- [( 2,False),( 3,False),( 4, True),( 5,False),
+            ( 6, True),( 7,False),( 8, True),( 9, True),
+            (10, True),(11,False),(12, True),(13,False),
+            (14, True),(15, True),(16, True),(17,False),
+            (18, True),(19,False),(20, True),(21, True),
+            (22, True),(23,False),(24, True),(25, True),
+            (26, True),(27, True),(28, True),(29,False)] ]
diff --git a/test/QC.hs b/test/QC.hs
new file mode 100644
--- /dev/null
+++ b/test/QC.hs
@@ -0,0 +1,13 @@
+{- copyright (c) sreservoir.
+   licensed under mit (x11). -}
+
+module Main where
+
+import Text.Regex.Less
+import Test.QuickCheck
+
+main :: IO ()
+main = do
+  putStr "all strings match null: " >> quickCheck matchEmpty
+
+matchEmpty a = truth (a =~ "")
