PHP Regex для обнаружения ОС

Я использую этот код для обнаружения ОС пользователя:

<? $osList = array ( /* -- WINDOWS -- */ 'Windows 10 (Windows NT 10.0)' => 'windows nt 10.0', 'Windows 8.1 (Windows NT 6.3)' => 'windows nt 6.3', 'Windows 8 (Windows NT 6.2)' => 'windows nt 6.2', 'Windows 7 (Windows NT 6.1)' => 'windows nt 6.1', 'Windows Vista (Windows NT 6.0)' => 'windows nt 6.0', 'Windows Server 2003 (Windows NT 5.2)' => 'windows nt 5.2', 'Windows XP (Windows NT 5.1)' => 'windows nt 5.1', 'Windows 2000 sp1 (Windows NT 5.01)' => 'windows nt 5.01', 'Windows 2000 (Windows NT 5.0)' => 'windows nt 5.0', 'Windows NT 4.0' => 'windows nt 4.0', 'Windows Me (Windows 9x 4.9)' => 'win 9x 4.9', 'Windows 98' => 'windows 98', 'Windows 95' => 'windows 95', 'Windows CE' => 'windows ce', 'Windows (version unknown)' => 'windows', /* -- MAC OS X -- */ 'Mac OS X Beta (Kodiak)' => 'Mac OS X beta', 'Mac OS X Cheetah' => 'Mac OS X 10.0', 'Mac OS X Puma' => 'Mac OS X 10.1', 'Mac OS X Jaguar' => 'Mac OS X 10.2', 'Mac OS X Panther' => 'Mac OS X 10.3', 'Mac OS X Tiger' => 'Mac OS X 10.4', 'Mac OS X Leopard' => 'Mac OS X 10.5', 'Mac OS X Snow Leopard' => 'Mac OS X 10.6', 'Mac OS X Lion' => 'Mac OS X 10.7', 'Mac OS X Mountain Lion' => 'Mac OS X 10.8', 'Mac OS X Mavericks' => 'Mac OS X 10.9', 'Mac OS X Yosemite' => 'Mac OS X 10.10', 'Mac OS X El Capitan' => 'Mac OS X 10.11', 'macOS Sierra' => 'Mac OS X 10.12', 'Mac OS X (version unknown)' => 'Mac OS X', 'Mac OS (classic)' => '(mac_powerpc)|(macintosh)', /* -- OTHERS -- */ 'OpenBSD' => 'openbsd', 'SunOS' => 'sunos', 'Ubuntu' => 'ubuntu', 'Linux (or Linux based)' => '(linux)|(x11)', 'QNX' => 'QNX', 'BeOS' => 'beos', 'OS2' => 'os/2', 'SearchBot'=>'(nuhk)|(googlebot)|(yammybot)|(openbot)|(slurp)|(msnbot)|(ask jeeves/teoma)|(ia_archiver)' ); $useragent = htmlspecialchars($_SERVER['HTTP_USER_AGENT']); $useragent = strtolower($useragent); foreach($osList as $os=>$match) { if (preg_match('/' . $match . '/i', $useragent)) { break; } else { $os = "Unknown"; } } ?> 

Проблема здесь: я использую OS X El Capitan (10.11.5), и этот код показывает, что я использую OS X Puma (10.1), потому что 'Mac OS X El Capitan' => 'Mac OS X 10.11' .

Итак, как я могу сообщить preg_match проверить, соответствует ли $match «XY (.Z)» ?

Вы можете добавить класс символов после 1 в случае OS X Puma, который будет соответствовать только следующему символу, а не цифре, например:

 'Mac OS X Puma' => 'Mac OS X 10.1[^0-9]', 

Это должно быть безопасно для надежного обнаружения версии 10.1 по сравнению с текущими и будущими версиями, такими как Mac OS X 10.1999.42


Следует отметить, что строки пользовательского агента, которые вы сейчас сопоставляете, имеют высокую вероятность быть разными между браузерами или даже редактироваться пользователями из своего браузера. Если требуется высокая степень успеха в сопоставлении, необходим подход, отличный от пользовательского нюхания.