将短码解析为数组

时间:2013-09-29 09:23:11

标签: php wordpress parsing

我需要在php中解析WordPress短代码到数组,例如:

[parrent_shortcode attribute='1'  attribute2='a']
    [shortcode atrribute1=true attribute2=true]This is first content[/shortcode]
    [shortcode atrribute1=false]This is second content[/shortcode]
[/parrent_shortcode]

成为:

Array(
    [name] => 'parrent_shortcode'
    [atts] => Array(
        [attribute] => '1'
        [attribute2] => 'a'
    )
    [content] => Array(
        [child1] => Array(
            [name] => 'shortcode'
            [atts] => Array(
                [atrribute1] => true
                [attribute2] => true
            )
            [content] => 'This is first content'
        )
        [child2] => Array(
            [name] => 'shortcode'
            [atts] => Array(
                [atrribute1] => false
            )
            [content] => 'This is second content'
        )
    )
)

此外,短代码可以没有parrent包装,也可以是没有内容的单一(自我封闭)。属性也可以包含空格。

我尝试使用爆炸来完成它但是有很多组合......

2 个答案:

答案 0 :(得分:6)

function get_pattern( $text ) {
    $pattern = get_shortcode_regex();
    preg_match_all( "/$pattern/s", $text, $c );
    return $c;
}

function parse_atts( $content ) {
    $content = preg_match_all( '/([^ ]*)=(\'([^\']*)\'|\"([^\"]*)\"|([^ ]*))/', trim( $content ), $c );
    list( $dummy, $keys, $values ) = array_values( $c );
    $c = array();
    foreach ( $keys as $key => $value ) {
        $value = trim( $values[ $key ], "\"'" );
        $type = is_numeric( $value ) ? 'int' : 'string';
        $type = in_array( strtolower( $value ), array( 'true', 'false' ) ) ? 'bool' : $type;
        switch ( $type ) {
            case 'int': $value = (int) $value; break;
            case 'bool': $value = strtolower( $value ) == 'true'; break;
        }
        $c[ $keys[ $key ] ] = $value;
    }
    return $c;
}

function the_shortcodes( &$output, $text, $child = false ) {

    $patts = get_pattern( $text );
    $t = array_filter( get_pattern( $text ) );
    if ( ! empty( $t ) ) {
        list( $d, $d, $parents, $atts, $d, $contents ) = $patts;
        $out2 = array();
        $n = 0;
        foreach( $parents as $k=>$parent ) {
            ++$n;
            $name = $child ? 'child' . $n : $n;
            $t = array_filter( get_pattern( $contents[ $k ] ) );
            $t_s = the_shortcodes( $out2, $contents[ $k ], true );
            $output[ $name ] = array( 'name' => $parents[ $k ] );
            $output[ $name ]['atts'] = parse_atts( $atts[ $k ] );
            $output[ $name ]['original_content'] = $contents[ $k ];
            $output[ $name ]['content'] = ! empty( $t ) && ! empty( $t_s ) ? $t_s : $contents[ $k ];
        }
    }
    return array_values( $output );
}

用法:

$text = "[parrent_shortcode attribute='1' attribute2='a b c']
    [shortcode atrribute1=true attribute2=\"j'aime\"]This is first content[/shortcode]
    [shortcode atrribute1=false]This is [shortcode/] content[/shortcode]
[/parrent_shortcode]
";
$output = array();
$output = the_shortcodes( $output, $text );
var_dump( array_values( $output ) );

这回应:

array (
  0 => 
  array (
    'name' => 'parrent_shortcode',
    'atts' => 
    array (
      'attribute' => 1,
      'attribute2' => 'a b c',
    ),
    'original_content' => '
    [shortcode atrribute1=true attribute2="j\'aime"]This is first content[/shortcode]
    [shortcode atrribute1=false]This is [shortcode/] content[/shortcode]
',
    'content' => 
    array (
      'child1' => 
      array (
        'name' => 'shortcode',
        'atts' => 
        array (
          'atrribute1' => true,
          'attribute2' => 'j\'aime',
        ),
        'original_content' => 'This is first content',
        'content' => 'This is first content',
      ),
      'child2' => 
      array (
        'name' => 'shortcode',
        'atts' => 
        array (
          'atrribute1' => false,
        ),
        'original_content' => 'This is [shortcode/] content',
        'content' => 
        array (
          0 => 
          array (
            'name' => 'shortcode',
            'atts' => 
            array (
            ),
            'original_content' => '',
            'content' => '',
          ),
        ),
      ),
    ),
  ),
)

答案 1 :(得分:0)

短代码API提供了一个名为do_shortcode()的函数 - 这样做你想要的吗? 该功能在此处定义:http://core.trac.wordpress.org/browser/tags/3.6.1/wp-includes/shortcodes.php#L181

另外,也许看看这里定义的get_shortcode_regex():http://core.trac.wordpress.org/browser/tags/3.6.1/wp-includes/shortcodes.php#L211 你应该能够挖掘出以某种方式解析短代码的正则表达式。