Search code examples
phpregexpreg-match

Extract multiples strings from one variable by using preg_match


I'm having troubles extracting several strings between tags from a variable, in order to echo them inside a span individually.
Thing is, the tags in question are determined by a variable, here is what it looks like :

<?php
    $string = "[en_UK]english1[/en_UK][en_UK]english2[/en_UK][fr_FR]francais1[/fr_FR][fr_FR]francais2[/fr_FR][fr_FR]francais3[/fr_FR]";
    $lang = "en_UK";

    preg_match("/(.[$lang]), (.[\/$lang])/", $string, $outputs_list);

    foreach ($outputs_list as $output) {
        echo "<span>".$output."/span>";
    }

    // in this exemple I want to output :
    // <span>english1</span>
    // <span>english2</span>
?>

It's my first time using preg_match and after trying so many differents things I'm kinda lost right now.
Basically I want to extract every strings contained between the tags [$lang] and [/$lang] (in my exemple $lang = "en_UK" but it will be determined by the user's cookies.

I'd like some help figuring this out if possible,

Thanks


Solution

  • [] in a regular expression makes a character class. I'm not sure what you're trying to do with the .s and , either. Your regex currently says:

    Any single character, an e, n, _, U, or K, a , and space, and again any single character, an e, n, _, U, K, but this time also allowing /.

    Regex demo: https://regex101.com/r/8pmy89/2

    I also believe you were grouping the wrong value. The () go around what you want to capture, know as a capture group.

    I think the regex you want is:

    \[$lang\](.+?)\[\/$lang\]
    

    Regex demo: https://regex101.com/r/8pmy89/3

    PHP Usage:

    $string = "[en_UK]english1[/en_UK][en_UK]english2[/en_UK][fr_FR]francais1[/fr_FR][fr_FR]francais2[/fr_FR][fr_FR]francais3[/fr_FR]";
    $lang = "en_UK";
    preg_match_all("/\[$lang\](.+?)\[\/$lang\]/", $string, $outputs_list);
    foreach ($outputs_list[1] as $output) {
        echo "<span>".$output."/span>";
    }
    

    PHP demo: https://eval.in/686086

    Preg_match vs. preg_match_all

    Preg_match only returns the first match(es) of a regex. Preg_match_all returns all matches of the regex. The 0 index has what the full regex matched. All subsequent indexes are each capture groups, e.g. 1 is the first capture group.

    Simple Demo: https://eval.in/686116

    $string = '12345';
    preg_match('/(\d)/', $string, $match);
    print_r($match);
    preg_match_all('/(\d)/', $string, $match);
    print_r($match);
    

    Output:

    Array
    (
        [0] => 1
        [1] => 1
    )
    

    ^ is preg_match, below is the preg_match_all

    Array
    (
        [0] => Array
            (
                [0] => 1
                [1] => 2
                [2] => 3
                [3] => 4
                [4] => 5
            )
    
        [1] => Array
            (
                [0] => 1
                [1] => 2
                [2] => 3
                [3] => 4
                [4] => 5
            )
    
    )