В вашем шаблоне вы не учитываете возможное подчеркивание.
Эта часть [0-9]?.[0-9]?[0-9]?[0-9]?[0-9]
соответствует необязательному ди git, любому символу, кроме символа новой строки, за которым следуют 3 необязательные цифры и ди git, которые также могут совпадать, например, x1
Вы получаете значение _13
, потому что вы повторяете сам захват, захватывая значение последней итерации.
В качестве альтернативы вы также можете использовать \K
для очистки буфера соответствия и получения соответствия только.
\bos\h+\K\d+(?:_\d+)*\b
\b
Граница слова os
Совпадение буквально \h+\K
Совпадение 1+ горизонтальных пробелов, затем забудьте, что было \d+(?:_\d+)*
Совпадение 1+ di git, возможно, повторяется _ и 1+ цифрами \b
Граница слова
Regex demo
Например
$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]);
Выход
13_3