diff --git a/inc/parser/lexer.php b/inc/parser/lexer.php
index 0887dde9383e7931ed9f080cd9b7a2900ffb684b..88deb7fe993d728d55c66e6a70f463fb0e50a156 100644
--- a/inc/parser/lexer.php
+++ b/inc/parser/lexer.php
@@ -138,60 +138,49 @@ class Doku_LexerParallelRegex {
             $cnt = count($this->_patterns);
             for ($i = 0; $i < $cnt; $i++) {
 
-                // Replace lookaheads / lookbehinds with marker
-                $m = "\1\1";
-                $pattern = preg_replace(
-                        array (
-                            '/\(\?(i|m|s|x|U)\)/U',
-                            '/\(\?(\-[i|m|s|x|U])\)/U',
-                            '/\(\?\=(.*)\)/sU',
-                            '/\(\?\!(.*)\)/sU',
-                            '/\(\?\<\=(.*)\)/sU',
-                            '/\(\?\<\!(.*)\)/sU',
-                            '/\(\?\:(.*)\)/sU',
-                        ),
-                        array (
-                            $m.'SO:\\1'.$m,
-                            $m.'SOR:\\1'.$m,
-                            $m.'LA:IS:\\1'.$m,
-                            $m.'LA:NOT:\\1'.$m,
-                            $m.'LB:IS:\\1'.$m,
-                            $m.'LB:NOT:\\1'.$m,
-                            $m.'GRP:\\1'.$m,
-                        ),
-                        $this->_patterns[$i]
-                    );
-                // Quote the rest
-                $pattern = str_replace(
-                    array('/', '(', ')'),
-                    array('\/', '\(', '\)'),
-                    $pattern
-                    );
-
-                // Restore lookaheads / lookbehinds
-                $pattern = preg_replace(
-                        array (
-                            '/'.$m.'SO:(.{1})'.$m.'/',
-                            '/'.$m.'SOR:(.{2})'.$m.'/',
-                            '/'.$m.'LA:IS:(.*)'.$m.'/sU',
-                            '/'.$m.'LA:NOT:(.*)'.$m.'/sU',
-                            '/'.$m.'LB:IS:(.*)'.$m.'/sU',
-                            '/'.$m.'LB:NOT:(.*)'.$m.'/sU',
-                            '/'.$m.'GRP:(.*)'.$m.'/sU',
-                        ),
-                        array (
-                            '(?\\1)',
-                            '(?\\1)',
-                            '(?=\\1)',
-                            '(?!\\1)',
-                            '(?<=\\1)',
-                            '(?<!\\1)',
-                            '(?:\\1)',
-                        ),
-                        $pattern
-                );
-
-                $this->_patterns[$i] = '('.$pattern.')';
+                /*
+                 * decompose the input pattern into "(", "(?", ")", 
+                 * "[...]", "[]..]", "[^]..]", "[...[:...:]..]", "\x"... 
+                 * elements.
+                 */ 
+                preg_match_all('/\\\\.|' . 
+                               '\(\?|' .
+                               '[()]|' .
+                               '\[\^?\]?(?:\\\\.|\[:[^]]*:\]|[^]\\\\])*\]|' .
+                               '[^[()\\\\]+/', $this->_patterns[$i], $elts);
+
+                $pattern = "";
+                $level = 0;
+
+                foreach ($elts[0] as $elt) {
+                    /*
+                     * for "(", ")" remember the nesting level, add "\" 
+                     * only to the non-"(?" ones.
+                     */
+
+                    switch($elt) {
+                    case '(':
+                        $pattern .= '\(';
+                        break;
+                    case ')':
+                        if ($level > 0)
+                            $level--; /* closing (? */
+                        else
+                            $pattern .= '\\';
+                        $pattern .= ')';
+                        break;
+                    case '(?':
+                        $level++;
+                        $pattern .= '(?';
+                        break;
+                    default:
+                        if (substr($elt, 0, 1) == '\\')
+                            $pattern .= $elt;
+                        else
+                            $pattern .= str_replace('/', '\/', $elt);
+                    }
+                }
+                $this->_patterns[$i] = "($pattern)";
             }
             $this->_regex = "/" . implode("|", $this->_patterns) . "/" . $this->_getPerlMatchingFlags();
         }
@@ -591,4 +580,4 @@ function Doku_Lexer_Escape($str) {
     return preg_replace($chars, $escaped, $str);
 }
 
-//Setup VIM: ex: et ts=4 enc=utf-8 :
+//Setup VIM: ex: et ts=4 sw=4 enc=utf-8 :