Search code examples
phpregexpreg-match

regular expression convert version wrong


Hey Community I have an issue I am using a regular expression on and instead of getting the full version I am getting the following _3 where I am supposed to get 13_3

This is how I am using the expression -

$useragent = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148";
$pattern = '/os ([0-9]?.[0-9]?[0-9]?[0-9]?[0-9])*/';
preg_match($pattern,strtolower($useragent),$m);

This is how I use it for Android -

$useragent = "Mozilla/5.0 (Linux; Android 8.1.0; moto e5 play Build/OPGS28.54-53-8-11; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.162 Mobile Safari/537.36";
$pattern = '/android ((\d+|\.).[^ ,);]+)/';
preg_match($pattern,strtolower($useragent),$m);

I am doing something wrong ?


Solution

  • In your pattern you are not accounting for the possible underscore.

    This part [0-9]?.[0-9]?[0-9]?[0-9]?[0-9] matches an optional digit, any char except a newline followed by 3 optional digits and a digit which might also match for example x1

    You get the value _13 because you are repeating the capturing itself, capturing the value of the last iteration.

    As an alternative you could also make use of \K to clear the match buffer and get the match only.

    \bos\h+\K\d+(?:_\d+)*\b
    
    • \b Word boundary
    • os Match literally
    • \h+\K Match 1+ horizontal whitespace chars, then forget what was matched
    • \d+(?:_\d+)* Match 1+ digit optionally repeated by _ and 1+ digits
    • \b Word boundary

    Regex demo

    For example

    $useragent = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148";
    $pattern = '/\bos\h+\K\d+(?:_\d+)*\b/';
    preg_match($pattern,strtolower($useragent),$m);
    print_r($m[0]);
    

    Output

    13_3