diff --git a/hspec-core.cabal b/hspec-core.cabal
--- a/hspec-core.cabal
+++ b/hspec-core.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: a6145f4a8f01c6344cd3a210ae77832823ae24ae25509d889b47e91d85661e2c
+-- hash: c6552ddea76009fa34e130109e1d7e036f4790640cc908c42633598692cc0c24
 
 name:             hspec-core
-version:          2.5.2
+version:          2.5.3
 license:          MIT
 license-file:     LICENSE
 copyright:        (c) 2011-2018 Simon Hengel,
diff --git a/src/Test/Hspec/Core/Formatters/Diff.hs b/src/Test/Hspec/Core/Formatters/Diff.hs
--- a/src/Test/Hspec/Core/Formatters/Diff.hs
+++ b/src/Test/Hspec/Core/Formatters/Diff.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE ViewPatterns #-}
 module Test.Hspec.Core.Formatters.Diff (
   Diff (..)
 , diff
@@ -8,17 +9,21 @@
 #endif
 ) where
 
+import           Prelude ()
+import           Test.Hspec.Core.Compat
+
 import           Data.Char
+import           Data.List (stripPrefix)
 import           Data.Algorithm.Diff
 
 diff :: String -> String -> [Diff String]
 diff expected actual = map (fmap concat) $ getGroupedDiff (partition expected) (partition actual)
 
 partition :: String -> [String]
-partition = mergeBackslashes . breakList isAlphaNum
+partition = filter (not . null) . mergeBackslashes . breakList isAlphaNum
   where
     mergeBackslashes xs = case xs of
-      ['\\'] : (y : ys) : zs -> ['\\', y] : ys : mergeBackslashes zs
+      ['\\'] : (splitEscape -> Just (escape, ys)) : zs -> ("\\" ++ escape) : ys : mergeBackslashes zs
       z : zs -> z : mergeBackslashes zs
       [] -> []
 
@@ -31,3 +36,55 @@
     cons x
       | null x = id
       | otherwise = (x :)
+
+splitEscape :: String -> Maybe (String, String)
+splitEscape xs = splitNumericEscape xs <|> (msum $ map split escapes)
+  where
+    split :: String -> Maybe (String, String)
+    split escape = (,) escape <$> stripPrefix escape xs
+
+splitNumericEscape :: String -> Maybe (String, String)
+splitNumericEscape xs = case span isDigit xs of
+  ("", _) -> Nothing
+  r -> Just r
+
+escapes :: [String]
+escapes = [
+    "ACK"
+  , "CAN"
+  , "DC1"
+  , "DC2"
+  , "DC3"
+  , "DC4"
+  , "DEL"
+  , "DLE"
+  , "ENQ"
+  , "EOT"
+  , "ESC"
+  , "ETB"
+  , "ETX"
+  , "NAK"
+  , "NUL"
+  , "SOH"
+  , "STX"
+  , "SUB"
+  , "SYN"
+  , "EM"
+  , "FS"
+  , "GS"
+  , "RS"
+  , "SI"
+  , "SO"
+  , "US"
+  , "a"
+  , "b"
+  , "f"
+  , "n"
+  , "r"
+  , "t"
+  , "v"
+  , "&"
+  , "'"
+  , "\""
+  , "\\"
+  ]
diff --git a/src/Test/Hspec/Core/Spec/Monad.hs b/src/Test/Hspec/Core/Spec/Monad.hs
--- a/src/Test/Hspec/Core/Spec/Monad.hs
+++ b/src/Test/Hspec/Core/Spec/Monad.hs
@@ -7,7 +7,6 @@
 , fromSpecList
 , runIO
 
-, mapSpecTree
 , mapSpecItem
 , mapSpecItem_
 , modifyParams
@@ -16,6 +15,7 @@
 import           Prelude ()
 import           Test.Hspec.Core.Compat
 
+import           Control.Arrow
 import           Control.Monad.Trans.Writer
 import           Control.Monad.IO.Class (liftIO)
 
@@ -49,8 +49,8 @@
 runIO :: IO r -> SpecM a r
 runIO = SpecM . liftIO
 
-mapSpecTree :: (SpecTree a -> SpecTree b) -> SpecWith a -> SpecWith b
-mapSpecTree f spec = runIO (runSpecM spec) >>= fromSpecList . map f
+mapSpecTree :: (SpecTree a -> SpecTree b) -> SpecM a r -> SpecM b r
+mapSpecTree f (SpecM specs) = SpecM (mapWriterT (fmap (second (map f))) specs)
 
 mapSpecItem :: (ActionWith a -> ActionWith b) -> (Item a -> Item b) -> SpecWith a -> SpecWith b
 mapSpecItem g f = mapSpecTree go
diff --git a/src/Test/Hspec/Core/Util.hs b/src/Test/Hspec/Core/Util.hs
--- a/src/Test/Hspec/Core/Util.hs
+++ b/src/Test/Hspec/Core/Util.hs
@@ -87,7 +87,7 @@
      pattern `isInfixOf` plain
   || pattern `isInfixOf` formatted
   where
-    plain = intercalate "/" (groups ++ [requirement])
+    plain = "/" ++ intercalate "/" (groups ++ [requirement]) ++ "/"
     formatted = formatRequirement path
 
 -- | The function `formatException` converts an exception to a string.
diff --git a/test/Helper.hs b/test/Helper.hs
--- a/test/Helper.hs
+++ b/test/Helper.hs
@@ -41,7 +41,7 @@
 import           System.Directory
 import           System.IO.Temp
 
-import           Test.Hspec.Meta
+import           Test.Hspec.Meta hiding (hspec, hspecResult)
 import           Test.QuickCheck hiding (Result(..))
 
 import qualified Test.Hspec.Core.Spec as H
diff --git a/test/Test/Hspec/Core/Formatters/DiffSpec.hs b/test/Test/Hspec/Core/Formatters/DiffSpec.hs
--- a/test/Test/Hspec/Core/Formatters/DiffSpec.hs
+++ b/test/Test/Hspec/Core/Formatters/DiffSpec.hs
@@ -1,15 +1,40 @@
+{-# LANGUAGE ScopedTypeVariables #-}
 module Test.Hspec.Core.Formatters.DiffSpec (spec) where
 
+import           Prelude ()
+import           Test.Hspec.Core.Compat
+
 import           Helper
 import           Data.Char
 
 import           Test.Hspec.Core.Formatters.Diff
 
+dropQuotes :: String -> String
+dropQuotes = init . tail
+
 spec :: Spec
 spec = do
   describe "partition" $ do
-    it "puts backslash-escaped characters into a separate chunks" $ do
-      partition (show "foo\nbar") `shouldBe` ["\"", "foo", "\\n", "bar", "\""]
+    context "with a single shown Char" $ do
+      it "never partitions a character escape" $ do
+        property $ \ (c :: Char) -> partition (show c) `shouldBe` ["'", dropQuotes (show c), "'"]
+
+    context "with a shown String" $ do
+      it "puts backslash-escaped characters into separate chunks" $ do
+        partition (show "foo\nbar") `shouldBe` ["\"", "foo", "\\n", "bar", "\""]
+
+      it "puts *arbitrary* backslash-escaped characters into separate chunks" $ do
+        property $ \ xs c ys ->
+          let
+            char = dropQuotes (show [c])
+            isEscaped = length char > 1
+            escape = tail char
+            sep = case ys of
+              x : _ | all isDigit escape && isDigit x || escape == "SO" && x == 'H' -> ["\\&"]
+              _ -> []
+            actual = partition (show (xs ++ c : ys))
+            expected = partition (init $ show xs) ++ [char] ++ sep ++ partition (tail $ show ys)
+          in isEscaped ==> actual `shouldBe` expected
 
   describe "breakList" $ do
     context "with a list where the predicate matches at the beginning and the end" $ do
diff --git a/test/Test/Hspec/Core/RunnerSpec.hs b/test/Test/Hspec/Core/RunnerSpec.hs
--- a/test/Test/Hspec/Core/RunnerSpec.hs
+++ b/test/Test/Hspec/Core/RunnerSpec.hs
@@ -44,9 +44,14 @@
 spec :: Spec
 spec = do
   describe "hspec" $ do
+
+    let
+      hspec args = withArgs ("--format=silent" : args) . H.hspec
+      hspec_ = hspec []
+
     it "evaluates examples Unmasked" $ do
       mvar <- newEmptyMVar
-      withArgs ["--format", "silent"] . H.hspec $ do
+      hspec_ $ do
         H.it "foo" $ do
           E.getMaskingState >>= putMVar mvar
       takeMVar mvar `shouldReturn` E.Unmasked
@@ -54,7 +59,7 @@
     it "runs finalizers" $ do
       mvar <- newEmptyMVar
       ref <- newIORef "did not run finalizer"
-      a <- async $ withArgs ["--format", "silent"] . H.hspec $ do
+      a <- async $ hspec_ $ do
           H.it "foo" $ do
             (putMVar mvar () >> threadDelay 10000000) `E.finally`
               writeIORef ref "ran finalizer"
@@ -63,12 +68,12 @@
       readIORef ref `shouldReturn` "ran finalizer"
 
     it "runs a spec" $ do
-      silence . H.hspec $ do
+      hspec_ $ do
         H.it "foobar" True
       `shouldReturn` ()
 
     it "exits with exitFailure if not all examples pass" $ do
-      silence . H.hspec $ do
+      hspec_ $ do
         H.it "foobar" False
       `shouldThrow` (== ExitFailure 1)
 
@@ -87,7 +92,7 @@
           ]
 
     it "stores a failure report in the environment" $ do
-      silence . ignoreExitCode . withArgs ["--seed", "23"] . H.hspec $ do
+      ignoreExitCode . hspec ["--seed", "23"] $ do
         H.describe "foo" $ do
           H.describe "bar" $ do
             H.it "example 1" True
@@ -166,11 +171,10 @@
 
 
     it "does not leak command-line options to examples" $ do
-      silence . withArgs ["--verbose"] $ do
-        H.hspec $ do
-          H.it "foobar" $ do
-            getArgs `shouldReturn` []
-        `shouldReturn` ()
+      hspec ["--diff"] $ do
+        H.it "foobar" $ do
+          getArgs `shouldReturn` []
+      `shouldReturn` ()
 
     context "when interrupted with ctrl-c" $ do
       it "prints summary immediately" $ do
@@ -211,7 +215,7 @@
         mvar <- newEmptyMVar
         sync <- newEmptyMVar
         threadId <- forkIO $ do
-          silence . H.hspec $ do
+          hspec_ $ do
             H.it "foo" $ do
               putMVar sync ()
               threadDelay 1000000
@@ -283,7 +287,7 @@
         child2 <- newQSem 0
         parent <- newQSem 0
         ref <- newIORef ""
-        ignoreExitCode . withArgs ["--fail-fast", "--format=silent", "-j", "2"] . H.hspec $ do
+        ignoreExitCode . hspec ["--fail-fast", "-j", "2"] $ do
           H.parallel $ do
             H.it "foo" $ do
               waitQSem child1
@@ -329,7 +333,7 @@
         e1 <- newMock
         e2 <- newMock
         e3 <- newMock
-        silence . withArgs ["-m", "/bar/example"] . H.hspec $ do
+        hspec ["-m", "/bar/example"] $ do
           H.describe "foo" $ do
             H.describe "bar" $ do
               H.it "example 1" $ mockAction e1
@@ -343,7 +347,7 @@
         e2 <- newMock
         e3 <- newMock
         e4 <- newMock
-        silence . withArgs ["-m", "/bar/example", "--skip", "example 3"] . H.hspec $ do
+        hspec ["-m", "/bar/example", "--skip", "example 3"] $ do
           H.describe "foo" $ do
             H.describe "bar" $ do
               H.it "example 1" $ mockAction e1
@@ -358,7 +362,7 @@
         e1 <- newMock
         e2 <- newMock
         e3 <- newMock
-        silence . withArgs ["-m", "foo", "-m", "baz"] . H.hspec $ do
+        hspec ["-m", "foo", "-m", "baz"] $ do
           H.describe "foo" $ do
             H.it "example 1" $ mockAction e1
           H.describe "bar" $ do
@@ -405,7 +409,7 @@
     context "with --qc-max-success" $ do
       it "tries QuickCheck properties specified number of times" $ do
         m <- newMock
-        silence . withArgs ["--qc-max-success", "23"] . H.hspec $ do
+        hspec ["--qc-max-success", "23"] $ do
           H.it "foo" $ property $ \(_ :: Int) -> do
             mockAction m
         mockCounter m `shouldReturn` 23
@@ -471,8 +475,12 @@
         r `shouldContain` "<span class=\"hspec-failure\">foo"
 
   describe "hspecResult" $ do
+    let
+      hspecResult args = withArgs ("--format=silent" : args) . H.hspecResult
+      hspecResult_ = hspecResult []
+
     it "returns a summary of the test run" $ do
-      silence . H.hspecResult $ do
+      hspecResult_ $ do
         H.it "foo" True
         H.it "foo" False
         H.it "foo" False
@@ -481,7 +489,7 @@
       `shouldReturn` H.Summary 5 2
 
     it "treats uncaught exceptions as failure" $ do
-      silence . H.hspecResult  $ do
+      hspecResult_  $ do
         H.it "foobar" throwException
       `shouldReturn` H.Summary 1 1
 
@@ -498,7 +506,7 @@
       r `shouldBe` ""
 
     it "does not let escape error thunks from failure messages" $ do
-      r <- silence . H.hspecResult $ do
+      r <- hspecResult_ $ do
         H.it "some example" (H.Result "" $ H.Failure Nothing . H.Reason $ "foobar" ++ undefined)
       r `shouldBe` H.Summary 1 1
 
@@ -506,7 +514,7 @@
       let n = 100
           t = 0.01
           dt = t * (fromIntegral n / 2)
-      r <- timeout dt . silence . withArgs ["-j", show n] . H.hspecResult . H.parallel $ do
+      r <- timeout dt . hspecResult ["-j", show n] . H.parallel $ do
         replicateM_ n (H.it "foo" $ sleep t)
       r `shouldBe` Just (H.Summary n 0)
 
@@ -521,7 +529,7 @@
               current <- atomicModifyIORef currentRef $ \x -> let y = succ x in (y, y)
               atomicModifyIORef highRef $ \x -> (max x current, ())
             stop = atomicModifyIORef currentRef $ \x -> (pred x, ())
-        r <- withArgs ["-j", show j] . H.hspecResult . H.parallel $ do
+        r <- hspecResult ["-j", show j] . H.parallel $ do
           replicateM_ n $ H.it "foo" $ E.bracket_ start stop $ sleep t
         r `shouldBe` H.Summary n 0
         high <- readIORef highRef
diff --git a/test/Test/Hspec/Core/UtilSpec.hs b/test/Test/Hspec/Core/UtilSpec.hs
--- a/test/Test/Hspec/Core/UtilSpec.hs
+++ b/test/Test/Hspec/Core/UtilSpec.hs
@@ -84,6 +84,11 @@
       let p = filterPredicate "ModuleA.ModuleB.foo does something"
       p (["ModuleA", "ModuleB", "foo"], "does something") `shouldBe` True
 
+    context "with an absolute path that begins or ends with a slash" $ do
+      it "succeeds" $ do
+        let p = filterPredicate "/foo/bar/baz/example 1/"
+        p (["foo", "bar", "baz"], "example 1") `shouldBe` True
+
   describe "formatRequirement" $ do
     it "creates a sentence from a subject and a requirement" $ do
       formatRequirement (["reverse"], "reverses a list") `shouldBe` "reverse reverses a list"
