Index: wp-includes/shortcodes.php
===================================================================
--- wp-includes/shortcodes.php	(revision 11721)
+++ wp-includes/shortcodes.php	(working copy)
@@ -175,7 +175,21 @@
 	$tagnames = array_keys($shortcode_tags);
 	$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
 
-	return '(.?)\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)';
+	return '(\[?)'										// possibly escape shortcode, part 1
+		. "\[($tagregexp)"								// a valid shortcode, e.g. [foo
+			. '(?=[\s\]\/])'							// Only match the shortcode if its followed by a space, a closing slash, or a closing bracket
+			. '(.*?)'									// maybe attributes
+			. '(\/)?'									// mark self-closing shortcode with a /
+			. '\]'
+		. '('
+			. '?(4)'									// stop if the shortcode is self-closing
+		. '|'
+			. '(?:'
+				. "((?:(?!\[(?:$tagregexp)\b).)*?)"		// look-ahead to make the shortcodes non-greedy
+				. '\[\/\2\]'							// stop on [/foo]
+			. ')?'
+		. ')?'											// allow for [foo] to be treated as [foo/]
+		. '(\]?)';										// possibly escape shortcode, part 2
 }
 
 /**
@@ -192,20 +206,26 @@
 function do_shortcode_tag($m) {
 	global $shortcode_tags;
 
-	// allow [[foo]] syntax for escaping a tag
-	if ($m[1] == '[' && $m[6] == ']') {
-		return substr($m[0], 1, -1);
-	}
+	$return = array_shift($m);
+	$begin = array_shift($m);
+	$end = array_pop($m);
 
-	$tag = $m[2];
-	$attr = shortcode_parse_atts($m[3]);
+	// allow [[foo]] and [[foo]bar[/foo]] syntax for escaping a tag
+	if ( $begin == '[' && $end == ']' )
+		return substr($return, 1, -1);
 
-	if ( isset($m[5]) ) {
+	$tag = array_shift($m);
+	$attr = array_shift($m);
+	$content = array_pop($m);
+	
+	$attr = shortcode_parse_atts($attr);
+
+	if ( $content ) {
 		// enclosing tag - extra parameter
-		return $m[1] . call_user_func($shortcode_tags[$tag], $attr, $m[5], $m[2]) . $m[6];
+		return call_user_func($shortcode_tags[$tag], $attr, $content, $tag);
 	} else {
 		// self-closing tag
-		return $m[1] . call_user_func($shortcode_tags[$tag], $attr, NULL, $m[2]) . $m[6];
+		return call_user_func($shortcode_tags[$tag], $attr, NULL, $tag);
 	}
 }
 
