diff --git a/src/Text/RegExp.hs b/src/Text/RegExp.hs
--- a/src/Text/RegExp.hs
+++ b/src/Text/RegExp.hs
@@ -37,8 +37,10 @@
 
   RegExp, fromString,
 
-  eps, char, sym, psym, anySym, alt, seq_, rep, rep1, opt, brep,
+  eps, char, sym, psym, anySym, noMatch, alt, seq_, rep, rep1, opt, brep,
 
+  perm,
+
   -- * Matching
 
   (=~), accept, matchingCount, fullMatch, partialMatch
@@ -92,6 +94,34 @@
 
 instance Data.String.IsString (RegExp Char) where
   fromString = parse
+
+-- |
+-- Matches a sequence of the given regular expressions in any
+-- order. For example, the regular expression
+-- 
+-- @
+-- perm (map char \"abc\")
+-- @
+-- 
+-- has the same meaning as
+-- 
+-- @
+-- abc|acb|bcc|bac|cba|cab
+-- @
+-- 
+-- and is represented as
+-- 
+-- @
+-- a(bc|cb)|b(ca|ac)|c(ba|ab)
+-- @
+-- 
+perm :: [RegExp c] -> RegExp c
+perm []  = eps
+perm [r] = r
+perm rs  = go rs []
+ where
+  go [p]    qs = p `seq_` perm qs
+  go (p:ps) qs = (p `seq_` perm (ps ++ qs)) `alt` go ps (p:qs)
 
 -- | 
 -- Alias for 'accept' specialized for Strings. Useful in combination
diff --git a/src/Text/RegExp/Data.hs b/src/Text/RegExp/Data.hs
--- a/src/Text/RegExp/Data.hs
+++ b/src/Text/RegExp/Data.hs
@@ -55,16 +55,16 @@
 epsW :: Semiring w => RegW w c
 epsW = RegW False one zero Eps
 
--- | Matches the given symbol.
--- 
-sym :: (Eq c, Show c) => c -> RegExp c
-sym c = psym (show c) (c==)
-
 -- | Matches the given character.
 -- 
 char :: Char -> RegExp Char
 char c = psym (quote c) (c==)
 
+-- | Matches the given symbol.
+-- 
+sym :: (Eq c, Show c) => c -> RegExp c
+sym c = psym (show c) (c==)
+
 quote :: Char -> String
 quote c | c `elem` " \\|*+?.[]{}^" = '\\' : [c]
         | otherwise                = [c]
@@ -81,6 +81,11 @@
 -- 
 anySym :: RegExp c
 anySym = psym "." (const True)
+
+-- | Does not match anything. 'noMatch' is an identity for 'alt'.
+-- 
+noMatch :: RegExp c
+noMatch = psym "[]" (const False)
 
 -- |
 -- Matches either of two regular expressions. For example @a+b@
diff --git a/src/quickcheck.lhs b/src/quickcheck.lhs
--- a/src/quickcheck.lhs
+++ b/src/quickcheck.lhs
@@ -16,6 +16,7 @@
 > import Test.QuickCheck.Batch
 > import Control.Monad ( ap, replicateM )
 > import Data.Char ( chr, ord )
+> import Data.List ( permutations )
 
 We import the semiring properties in order to check them for the
 defined instances. We also define our own `sum` function for
@@ -59,6 +60,7 @@
 >       checks (partial'match'spec LeftLong.matching getLeftLong)
 >     runTests (pad "parse printed regexp") options [run parse'printed]
 >     runChecks "lazy infinite regexps" infinite'regexp'checks
+>     runTests "permutation parsing" options [run perm'parser'check]
 >  where
 >   options = defOpt { no_of_tests = 1000, length_of_tests = 60 }
 >   runChecks s = runTests (pad s) options . checks
@@ -326,3 +328,22 @@
 >  where
 >   mkAnBnCn n = brep (n,n) (sym 2) `seq_` brep (n,n) (sym 3)
 >          `alt` seq_ (sym 1) (mkAnBnCn (n+1))
+
+The library provides a combinator that matches a list of regular
+expressions in sequence, each occurring once in any order.
+
+> perm'parser'check :: String -> Bool
+> perm'parser'check cs = all (accept (perm (map char s))) (permutations s)
+>  where s = take 5 cs
+
+We restrict the test to at most 5! (that is five factorial)
+permutations because otherwise there are too many. Note that it is
+possible to match much longer permutations:
+
+    ghci> accept (perm (map char ['a'..'z'])) $ reverse ['a'..'z']
+    True
+    (0.05 secs, 8706356 bytes)
+
+But matching `perm (map char ['a'..'z'])` against *all* permutations
+of ['a'..'z'] takes too long.
+
diff --git a/weighted-regexp.cabal b/weighted-regexp.cabal
--- a/weighted-regexp.cabal
+++ b/weighted-regexp.cabal
@@ -1,5 +1,5 @@
 Name:          weighted-regexp
-Version:       0.1.0.0
+Version:       0.1.1.0
 Cabal-Version: >= 1.6
 Synopsis:      Weighted Regular Expression Matcher
 Description:
