函数文档

get_shortcode_regex()

💡 云策文档标注

概述

get_shortcode_regex() 函数用于生成一个正则表达式,用于在内容中搜索已注册的短代码。它支持指定短代码标签列表,并返回包含6个子匹配的正则表达式,以帮助解析短代码的结构。

关键要点

  • 函数返回一个正则表达式字符串,用于匹配和解析短代码。
  • 正则表达式包含6个子匹配:1) 可选的额外 [ 用于转义;2) 短代码名称;3) 短代码参数列表;4) 自闭合标签的 /;5) 短代码包裹的内容;6) 可选的额外 ] 用于转义。
  • 参数 $tagnames 可选,默认为所有已注册短代码,用于指定要查找的短代码列表。
  • 警告:更改此正则表达式需同步更新 do_shortcode_tag() 和 strip_shortcode_tag() 等相关函数。

代码示例

/**
 * Detect shortcodes in the global $post.
 */
function wpdocs_detect_shortcode() {
    global $post;
    $pattern = get_shortcode_regex();

    if (   preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
        && array_key_exists( 2, $matches )
        && in_array( 'your-shortcode', $matches[2] )
    ) {
        // shortcode is being used
    }
}
add_action( 'wp', 'wpdocs_detect_shortcode' );

注意事项

  • 此函数生成的正则表达式与 do_shortcode_tag() 和 strip_shortcode_tag() 紧密相关,修改时需确保一致性。
  • 在 WordPress 4.4.0 版本中引入了 $tagnames 参数,允许自定义短代码搜索范围。
  • 使用 preg_match_all() 时,$matches 数组的第二个元素包含所有匹配的短代码名称,可用于进一步处理。

📄 原文内容

Retrieves the shortcode regular expression for searching.

Description

The regular expression combines the shortcode tags in the regular expression in a regex class.

The regular expression contains 6 different sub matches to help with parsing.

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 [[]]

Parameters

$tagnamesarrayoptional
List of shortcodes to find. Defaults to all registered shortcodes.

Default:null

Return

string The shortcode search regular expression.

Source

function get_shortcode_regex( $tagnames = null ) {
	global $shortcode_tags;

	if ( empty( $tagnames ) ) {
		$tagnames = array_keys( $shortcode_tags );
	}
	$tagregexp = implode( '|', array_map( 'preg_quote', $tagnames ) );

	/*
	 * WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag().
	 * Also, see shortcode_unautop() and shortcode.js.
	 */

	// phpcs:disable Squiz.Strings.ConcatenationSpacing.PaddingFound -- don't remove regex indentation
	return '\['                             // Opening bracket.
		. '(\[?)'                           // 1: Optional second opening bracket for escaping shortcodes: [[tag]].
		. "($tagregexp)"                     // 2: Shortcode name.
		. '(?![\w-])'                       // Not followed by word character or hyphen.
		. '('                                // 3: Unroll the loop: Inside the opening shortcode tag.
		.     '[^\]\/]*'                   // Not a closing bracket or forward slash.
		.     '(?:'
		.         '\/(?!\])'               // A forward slash not followed by a closing bracket.
		.         '[^\]\/]*'               // Not a closing bracket 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 bracket for escaping shortcodes: [[tag]].
	// phpcs:enable
}

Changelog

Version Description
4.4.0 Added the $tagnames parameter.
2.5.0 Introduced.

User Contributed Notes

  1. Skip to note 3 content

    Example

    /**
     * Detect shortcodes in the global $post.
     */
    function wpdocs_detect_shortcode() {
    	global $post;
    	$pattern = get_shortcode_regex();
    
    	if (   preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
    		&& array_key_exists( 2, $matches )
    		&& in_array( 'your-shortcode', $matches[2] )
    	) {
    		// shortcode is being used
    	}
    }
    add_action( 'wp', 'wpdocs_detect_shortcode' );

    This can only be used when $post is available. ‘wp’ is the earliest action you can hook into to get access to it.

    The following code is an adjustment of the first example, but able to also search all posts on the index page.

    /**
     * Detect shortcodes in the global $post.
     */
    function wpdocs_detect_shortcode() {
    	global $wp_query;	
    	$posts = $wp_query->posts;
    	$pattern = get_shortcode_regex();
        
    	foreach ( $posts as $post ) {
    		if ( preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
    			&& array_key_exists( 2, $matches )
    			&& in_array( 'videoannotation', $matches[2] )
    		) {
    			// enque my css and js
    			break;	
    		}    
    	}
    }
    add_action( 'wp', 'wpdocs_detect_shortcode' );

  2. Skip to note 4 content

    Each element of the $matches array given to you by preg_match_all() is itself an array. If your post content contains multiple shortcodes, each of those arrays contains one element for each shortcode. This sort of code gets them.

    function wpdocs_detect_shortcode() {
    	global $post;
    
    	$pattern = get_shortcode_regex();
    
    	if ( preg_match_all( '/' . $pattern . '/s', $post->post_content, $matches ) && array_key_exists( 2, $matches ) ) {
    		$shortcode_count  = count( $matches[2] );
    		$shortcodes_array = $matches[2];
    		$atts_array       = $matches[3];
    
    		for ( $i = 0; $i < $shortcode_count; $i++ ) {
    			$shortcode = $shortcodes_array[ $i ];
    			$atts      = shortcode_parse_atts( $atts_array[ $i ] );
    		}
    	}
    }