Search code examples
phparraysregexshortcode

php - regex/preg_match_all (child) shortcode attribute


I try to regex/preg_match_all shortcodes (in wordpress) in order to get a specific attribute value, however my php code partially works...

In fact I success to regex parent shortcodes but not children shortcodes.

My shortcode looks like to this:

[to_custom_font family="Lato;900italic" decoration="" style="normal"]Content[/to_custom_font]

Here my php code:

preg_match_all("/$pattern/",$post_content,$matches);
$to_shortcode = array_keys($matches[2],'to_custom_font');
if (!empty($to_shortcode)) {
    foreach($to_shortcode as $sc) {
        preg_match('/family="([^"]+)"/', $matches[3][$sc], $match);
        $font_infos = explode(';',$match[1]);
        $family     = $font_infos[0];
        $variant    = $font_infos[1];
        $font       = $family.':'.$variant;

        if(!in_array($font, $available_families)){
            $available_font = array_merge($available_font, array($font => $post_id));
        }

    }
}

It works with parent shortcodes but not with children shortcodes:

[to_custom_font family="Lato;900italic" decoration="" style="normal"]Content[/to_custom_font] //parent shortcode

[to_section attr="" attr3=""]
[to_custom_font family="Lato;900italic" decoration="" style="normal"]Content[/to_custom_font]//child shortcode
[/to_section]

It seems that the problem comes from here :

preg_match_all("/$pattern/",$post_content,$matches);

$matches only return parent shortcodes. And I need to get all children levels...

My aim with this code is to get all value family="" attribute. Maybe there is a better way to do it...


Solution

  • If I understand your question, this might be what you need

    $string = '[to_custom_font family="Lato;900italic" decoration="" style="normal"]Content[/to_custom_font] //parent shortcode[to_section attr="" attr3=""][to_custom_font family="Lato;900italic" decoration="" style="normal"]Content[/to_custom_font]//child shortcode[/to_section]';
    
    preg_match_all('/family="([^"]+)"/', $string, $matches);    
    foreach ($matches[1] as $match) {
        echo $match . "\n";
    }
    
    // or use print_r() to see the whole array
    
    print_r($matches);
    
    ?>
    

    Output:

    Lato;900italic
    Lato;900italic
    
    Array
    (
        [0] => Array
            (
                [0] => family="Lato;900italic"
                [1] => family="Lato;900italic"
            )
    
        [1] => Array
            (
                [0] => Lato;900italic
                [1] => Lato;900italic
            )
    
    )
    

    PHP demo | Regex demo