Search code examples
phpregexpreg-match

php regex to extract single parameter value from string


I'm working with a string containing parameters, separated by some special characters in PHP with preg_match

An example could be like this one, which has four parameters.

1stparm?#?1111?@?2ndParm?#?2222?@?3rdParm?#?3333?@?4thparm?#?444?@?

Each parameter name is followed by ?#?, and its value is right next to it, ending with ?@? (note: values can be strings or numbers, and even special characters)

I've probably overcomplicated my regex, which works in SOME cases, but not if I search for the last parameter in the string..

This example returns 2222 as the correct value (in group 1) for 2ndParm

(?:.*)2ndParm\?#\?(.*?)\?@\?(?=.)(.*)

but it fails if 2ndParm is the last one in the string as in the following example:

1stparm?#?1111?@?2ndParm?#?2222?@?

I'd also appreciate help in just returning one group with my result.. i havent been able to do so, but since I always get the one I'm interested in group 1, I can get it easily anyway.


Solution

  • You can use

    (?P<key>.+?)
    \Q?#?\E
    (?P<value>.+?)
    \Q?@?\E
    

    in verbose mode, see a demo on regex101.com.


    The \Q...\E construct disables the ? and # "super-powers" (no need to escape them here).
    In PHP this could be

    <?php
    $string = "1stparm?#?1111?@?2ndParm?#?2222?@?3rdParm?#?3333?@?4thparm?#?444?@?";
    
    $regex = "~(?P<key>.+?)\Q?#?\E(?P<value>.+?)\Q?@?\E~";
    
    preg_match_all($regex, $string, $matches, PREG_SET_ORDER);
    
    foreach ($matches as $match) {
        echo $match["key"] . " = " . $match["value"] . "\n";
    }
    
    ?>
    

    Which yields

    1stparm = 1111
    2ndParm = 2222
    3rdParm = 3333
    4thparm = 444
    


    Or shorter:

    $result = array_map(
        function($x) {return array($x["key"] => $x["value"]);}, $matches);
    print_r($result);