Index: wp-includes/shortcodes.php
===================================================================
--- wp-includes/shortcodes.php	(revision 18662)
+++ wp-includes/shortcodes.php	(working copy)
@@ -148,7 +148,7 @@
 		return $content;
 
 	$pattern = get_shortcode_regex();
-	return preg_replace_callback('/'.$pattern.'/s', 'do_shortcode_tag', $content);
+	return preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content );
 }
 
 /**
@@ -159,11 +159,12 @@
  *
  * The regular expression contains 6 different sub matches to help with parsing.
  *
- * 1/6 - An extra [ or ] to allow for escaping shortcodes with double [[]]
+ * 1 - An extra [ to allow for escaping shortcodes with double [[]]
  * 2 - The shortcode name
  * 3 - The shortcode argument list
  * 4 - The self closing /
  * 5 - The content of a shortcode when it wraps some content.
+ * 6 - An extra ] to allow for escaping shortcodes with double [[]]
  *
  * @since 2.5
  * @uses $shortcode_tags
@@ -175,8 +176,42 @@
 	$tagnames = array_keys($shortcode_tags);
 	$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
 
-	// WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcodes()
-	return '(.?)\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)';
+	// WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag()
+	return
+		  '\\['                              // Opening bracket
+		. '(\\[?)'                           // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
+		. "($tagregexp)"                     // 2: Shortcode name
+		. '\\b'                              // Word boundary
+		. '('                                // 3: Unroll the loop: Inside the opening shortcode tag
+		.     '[^\\]\'"\\/]*'                // Not a closing bracket, single or double quote, or forward slash
+		.     '(?:'
+		.         '(?:'
+		.             "'[^']*+'"             // Anything in single quotes
+		.         '|'
+		.             '"[^"]*+"'             // Anything in double quotes
+		.         '|'
+		.             '\\/(?!\\])'           // A forward slash not followed by a closing bracket
+		.         ')'
+		.         '[^\\]\'"\\/]*'            // Not a closing bracket, single or double quote, or forward slash
+		.     ')*?'
+		. ')'
+		. '(?:'
+		.     '(\\/)'                        // 4: Self closing tag ...
+		.     '\\]'                          // ... and closing bracket
+		. '|'
+		.     '\\]'                          // Closing bracket
+		.     '(?:'
+		.         '('                        // 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
+		.             '[^\\[]*+'             // Not an opening bracket
+		.             '(?:'
+		.                 '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
+		.                 '[^\\[]*+'         // Not an opening bracket
+		.             ')*+'
+		.         ')'
+		.         '\\[\\/\\2\\]'             // Closing shortcode tag
+		.     ')?'
+		. ')'
+		. '(\\]?)';                          // 6: Optional second closing brocket for escaping shortcodes: [[tag]]
 }
 
 /**
@@ -290,9 +325,18 @@
 
 	$pattern = get_shortcode_regex();
 
-	return preg_replace('/'.$pattern.'/s', '$1$6', $content);
+	return preg_replace_callback( "/$pattern/s", 'strip_shortcode_tag', $content );
 }
 
+function strip_shortcode_tag( $m ) {
+	// allow [[foo]] syntax for escaping a tag
+	if ( $m[1] == '[' && $m[6] == ']' ) {
+		return substr($m[0], 1, -1);
+	}
+
+	return $m[1] . $m[6];
+}
+
 add_filter('the_content', 'do_shortcode', 11); // AFTER wpautop()
 
-?>
\ No newline at end of file
+?>
Index: wp-includes/formatting.php
===================================================================
--- wp-includes/formatting.php	(revision 18662)
+++ wp-includes/formatting.php	(working copy)
@@ -232,16 +232,54 @@
  * @param string $pee The content.
  * @return string The filtered content.
  */
-function shortcode_unautop($pee) {
+function shortcode_unautop( $pee ) {
 	global $shortcode_tags;
 
-	if ( !empty($shortcode_tags) && is_array($shortcode_tags) ) {
-		$tagnames = array_keys($shortcode_tags);
-		$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
-		$pee = preg_replace('/<p>\\s*?(\\[(' . $tagregexp . ')\\b.*?\\/?\\](?:.+?\\[\\/\\2\\])?)\\s*<\\/p>/s', '$1', $pee);
+	if ( empty( $shortcode_tags ) || !is_array( $shortcode_tags ) ) {
+		return $pee;
 	}
 
-	return $pee;
+	$tagregexp = join( '|', array_map( 'preg_quote', array_keys( $shortcode_tags ) ) );
+
+	$pattern =
+		  '/'
+		. '<p>'                              // Opening paragraph
+		. '\\s*+'                            // Optional leading whitespace
+		. '('                                // 1: The shortcode
+		.     '\\['                          // Opening bracket
+		.     "($tagregexp)"                 // 2: Shortcode name
+		.     '\\b'                          // Word boundary
+		                                     // Unroll the loop: Inside the opening shortcode tag
+		.     '[^\\]\'"\\/]*'                // Not a closing bracket, single or double quote, or forward slash
+		.     '(?:'
+		.         '(?:'
+		.             "'[^']*+'"             // Anything in single quotes
+		.         '|'
+		.             '"[^"]*+"'             // Anything in double quotes
+		.         '|'
+		.             '\\/(?!\\])'           // A forward slash not followed by a closing bracket
+		.         ')'
+		.         '[^\\]\'"\\/]*'            // Not a closing bracket, single or double quote, or forward slash
+		.     ')*?'
+		.     '(?:'
+		.         '\\/\\]'                   // Self closing tag and closing bracket
+		.     '|'
+		.         '\\]'                      // Closing bracket
+		.         '(?:'                      // Unroll the loop: Optionally, anything between the opening and closing shortcode tags
+		.             '[^\\[]*+'             // Not an opening bracket
+		.             '(?:'
+		.                 '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
+		.                 '[^\\[]*+'         // Not an opening bracket
+		.             ')*+'
+		.             '\\[\\/\\2\\]'         // Closing shortcode tag
+		.         ')?'
+		.     ')'
+		. ')'
+		. '\\s*+'                            // optional trailing whitespace
+		. '<\\/p>'                           // closing paragraph
+		. '/s';
+
+	return preg_replace( $pattern, '$1', $pee );
 }
 
 /**
