Index: wp-includes/shortcodes.php
===================================================================
--- wp-includes/shortcodes.php	(revision 1767)
+++ wp-includes/shortcodes.php	(working copy)
@@ -175,7 +175,20 @@
 	$tagnames = array_keys($shortcode_tags);
 	$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
 
-	return '(.?)\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)';
+	return '(\[?)'										// possibly escape shortcode, part 1
+		. "\[($tagregexp)\b"							// a valid shortcode, e.g. [foo
+			. '(.*?)'									// 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
 }
 
 /**
@@ -191,21 +204,28 @@
  */
 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);
+	
+	// allow [[foo]] and [[foo]bar[/foo]] syntax for escaping a tag
+	if ($begin == '[' && $end == ']') {
+		return substr($return, 1, -1);
 	}
 
-	$tag = $m[2];
-	$attr = shortcode_parse_atts($m[3]);
+	$tag = array_shift($m);
+	$attr = array_shift($m);
+	$content = array_pop($m);
+	
+	$attr = shortcode_parse_atts($attr);
 
-	if ( isset($m[5]) ) {
+	if ( $content ) {
 		// enclosing tag - extra parameter
-		return $m[1] . call_user_func($shortcode_tags[$tag], $attr, $m[5], $m[2]) . $m[6];
+		return $begin . call_user_func($shortcode_tags[$tag], $attr, $content, $tag) . $end;
 	} else {
 		// self-closing tag
-		return $m[1] . call_user_func($shortcode_tags[$tag], $attr, NULL, $m[2]) . $m[6];
+		return $begin . call_user_func($shortcode_tags[$tag], $attr, NULL, $tag) . $end;
 	}
 }
 
