Index: src/wp-includes/formatting.php
===================================================================
--- src/wp-includes/formatting.php	(revision 33907)
+++ src/wp-includes/formatting.php	(working copy)
@@ -216,9 +216,24 @@
 
 	// Look for shortcodes and HTML elements.
 
-	$tagnames = array_keys( $shortcode_tags );
-	$tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) );
-	$tagregexp = "(?:$tagregexp)(?![\\w-])"; // Excerpt of get_shortcode_regex().
+	preg_match_all( '@\[/?([^\s\[\]/]++)@', $text, $matches );
+	$tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] );
+	$found_shortcodes = ! empty( $tagnames );
+	if ( $found_shortcodes ) {
+		$tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) );
+		$tagregexp = "(?:$tagregexp)(?![\\w-])"; // Excerpt of get_shortcode_regex().
+		$shortcode_regex =
+			  '\['              // Find start of shortcode.
+			. '[\/\[]?'         // Shortcodes may begin with [/ or [[
+			. $tagregexp        // Only match registered shortcodes, because performance.
+			. '(?:'
+			.     '[^\[\]<>]+'  // Shortcodes do not contain other shortcodes. Quantifier critical.
+			. '|'
+			.     '<[^\[\]>]*>' // HTML elements permitted. Prevents matching ] before >.
+			. ')*+'             // Possessive critical.
+			. '\]'              // Find end of shortcode.
+			. '\]?';            // Shortcodes may end with ]]
+	}
 
 	$comment_regex =
 		  '!'           // Start of comment, after the <.
@@ -228,51 +243,39 @@
 		. ')*+'         // Loop possessively.
 		. '(?:-->)?';   // End of comment. If not found, match all input.
 
-	$shortcode_regex =
-		  '\['              // Find start of shortcode.
-		. '[\/\[]?'         // Shortcodes may begin with [/ or [[
-		. $tagregexp        // Only match registered shortcodes, because performance.
-		. '(?:'
-		.     '[^\[\]<>]+'  // Shortcodes do not contain other shortcodes. Quantifier critical.
+	$html_regex =			 // Needs replaced with wp_html_split() per Shortcode API Roadmap.
+		  '<'                // Find start of element.
+		. '(?(?=!--)'        // Is this a comment?
+		.     $comment_regex // Find end of comment.
 		. '|'
-		.     '<[^\[\]>]*>' // HTML elements permitted. Prevents matching ] before >.
-		. ')*+'             // Possessive critical.
-		. '\]'              // Find end of shortcode.
-		. '\]?';            // Shortcodes may end with ]]
+		.     '[^>]*>?'      // Find end of element. If not found, match all input.
+		. ')';
+		
+	if ( $found_shortcodes ) {
+		$regex = '/(' . $html_regex . '|' . $shortcode_regex . ')/s';
+	} else {
+		$regex = '/(' . $html_regex . ')/s';
+	}
 
-	$regex =
-		  '/('                   // Capture the entire match.
-		.     '<'                // Find start of element.
-		.     '(?(?=!--)'        // Is this a comment?
-		.         $comment_regex // Find end of comment.
-		.     '|'
-		.         '[^>]*>'       // Find end of element.
-		.     ')'
-		. '|'
-		.     $shortcode_regex   // Find shortcodes.
-		. ')/s';
-
 	$textarr = preg_split( $regex, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
 
 	foreach ( $textarr as &$curl ) {
 		// Only call _wptexturize_pushpop_element if $curl is a delimiter.
 		$first = $curl[0];
-		if ( '<' === $first && '<!--' === substr( $curl, 0, 4 ) ) {
-			// This is an HTML comment delimeter.
+		if ( '<' === $first ) {
+			if ( '<!--' === substr( $curl, 0, 4 ) ) {
+				// This is an HTML comment delimeter.
+				continue;
+			} else {
+				// This is an HTML element delimiter.
+				_wptexturize_pushpop_element( $curl, $no_texturize_tags_stack, $no_texturize_tags );
+			}
 
-			continue;
-
-		} elseif ( '<' === $first && '>' === substr( $curl, -1 ) ) {
-			// This is an HTML element delimiter.
-
-			_wptexturize_pushpop_element( $curl, $no_texturize_tags_stack, $no_texturize_tags );
-
 		} elseif ( '' === trim( $curl ) ) {
 			// This is a newline between delimiters.  Performance improves when we check this.
-
 			continue;
 
-		} elseif ( '[' === $first && 1 === preg_match( '/^' . $shortcode_regex . '$/', $curl ) ) {
+		} elseif ( '[' === $first && $found_shortcodes && 1 === preg_match( '/^' . $shortcode_regex . '$/', $curl ) ) {
 			// This is a shortcode delimiter.
 
 			if ( '[[' !== substr( $curl, 0, 2 ) && ']]' !== substr( $curl, -2 ) ) {
Index: src/wp-includes/shortcodes.php
===================================================================
--- src/wp-includes/shortcodes.php	(revision 33907)
+++ src/wp-includes/shortcodes.php	(working copy)
@@ -195,18 +195,17 @@
 	if (empty($shortcode_tags) || !is_array($shortcode_tags))
 		return $content;
 
-	$tagnames = array_keys($shortcode_tags);
-	$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
-	$pattern = "/\\[($tagregexp)/s";
+	// Find all registered tag names in $content.
+	preg_match_all( '@\[([^\s\[\]/]++)@', $content, $matches );
+	$tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] );
 
-	if ( 1 !== preg_match( $pattern, $content ) ) {
-		// Avoids parsing HTML when there are no shortcodes or embeds anyway.
+	if ( empty( $tagnames ) ) {
 		return $content;
 	}
 
-	$content = do_shortcodes_in_html_tags( $content, $ignore_html );
+	$content = do_shortcodes_in_html_tags( $content, $ignore_html, $tagnames );
 
-	$pattern = get_shortcode_regex();
+	$pattern = get_shortcode_regex( $tagnames );
 	$content = preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content );
 
 	// Always restore square braces so we don't break things like <!--[if IE ]>
@@ -234,11 +233,15 @@
  *
  * @global array $shortcode_tags
  *
+ * @param array $tagnames List of shortcodes to find. Optional. Defaults to all registered shortcodes.
  * @return string The shortcode search regular expression
  */
-function get_shortcode_regex() {
+function get_shortcode_regex( $tagnames = null ) {
 	global $shortcode_tags;
-	$tagnames = array_keys($shortcode_tags);
+
+	if ( empty( $tagnames ) ) {
+		$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_shortcode_tag()
@@ -324,15 +327,16 @@
  *
  * @param string $content Content to search for shortcodes
  * @param bool $ignore_html When true, all square braces inside elements will be encoded.
+ * @param array $tagnames List of shortcodes to find.
  * @return string Content with shortcodes filtered out.
  */
-function do_shortcodes_in_html_tags( $content, $ignore_html ) {
+function do_shortcodes_in_html_tags( $content, $ignore_html, $tagnames ) {
 	// Normalize entities in unfiltered HTML before adding placeholders.
 	$trans = array( '&#91;' => '&#091;', '&#93;' => '&#093;' );
 	$content = strtr( $content, $trans );
 	$trans = array( '[' => '&#91;', ']' => '&#93;' );
 
-	$pattern = get_shortcode_regex();
+	$pattern = get_shortcode_regex( $tagnames );
 	$textarr = wp_html_split( $content );
 
 	foreach ( $textarr as &$element ) {
@@ -532,9 +536,17 @@
 	if (empty($shortcode_tags) || !is_array($shortcode_tags))
 		return $content;
 
-	$content = do_shortcodes_in_html_tags( $content, true );
+	// Find all registered tag names in $content.
+	preg_match_all( '@\[([^\s\[\]/]++)@', $content, $matches );
+	$tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] );
 
-	$pattern = get_shortcode_regex();
+	if ( empty( $tagnames ) ) {
+		return $content;
+	}
+
+	$content = do_shortcodes_in_html_tags( $content, true, $tagnames );
+
+	$pattern = get_shortcode_regex( $tagnames );
 	$content = preg_replace_callback( "/$pattern/s", 'strip_shortcode_tag', $content );
 
 	// Always restore square braces so we don't break things like <!--[if IE ]>
Index: tests/phpunit/tests/formatting/WPTexturize.php
===================================================================
--- tests/phpunit/tests/formatting/WPTexturize.php	(revision 33907)
+++ tests/phpunit/tests/formatting/WPTexturize.php	(working copy)
@@ -374,8 +374,8 @@
 				"word [&#8216;word word",
 			),
 			array(
-				"word <'word word", // Invalid HTML input triggers the apos in a word pattern.
-				"word <&#8217;word word",
+				"word <'word word", // Invalid HTML
+				"word <'word word",
 			),
 			array(
 				"word &lt;'word word", // Valid HTML input makes curly quotes.
@@ -403,7 +403,7 @@
 			),
 			array(
 				"word<'word word",
-				"word<&#8217;word word",
+				"word<'word word",
 			),
 			array(
 				"word&lt;'word word",
@@ -431,7 +431,7 @@
 			),
 			array(
 				"word <' word word",
-				"word <&#8217; word word",
+				"word <' word word",
 			),
 			array(
 				"word &lt;' word word",
@@ -459,7 +459,7 @@
 			),
 			array(
 				"word<' word word",
-				"word<&#8217; word word",
+				"word<' word word",
 			),
 			array(
 				"word&lt;' word word",
@@ -610,8 +610,8 @@
 				'word [&#8220;word word',
 			),
 			array(
-				'word <"word word', // Invalid HTML input triggers the closing quote pattern.
-				'word <&#8221;word word',
+				'word <"word word', // Invalid HTML
+				'word <"word word',
 			),
 			array(
 				'word &lt;"word word',
@@ -643,7 +643,7 @@
 			),
 			array(
 				'word<"word word',
-				'word<&#8221;word word',
+				'word<"word word',
 			),
 			array(
 				'word&lt;"word word',
@@ -1312,7 +1312,7 @@
 			),
 			array(
 				'<br [gallery ...] ... /',
-				'<br [gallery ...] &#8230; /',
+				'<br [gallery ...] ... /',
 			),
 			array(
 				'<br ... />',
@@ -1352,7 +1352,7 @@
 			),
 			array(
 				'<br [[gallery ...]] ... /',
-				'<br [[gallery ...]] &#8230; /',
+				'<br [[gallery ...]] ... /',
 			),
 			array(
 				'[[gallery ...]]...[[gallery ...]]',
