在PHP中使用正则表达式检测iOS操作系统

3

我来这里寻找有关通过用户代理嗅探iOS 6的答案,并在这里找到了一个很好的回答:如何通过用户代理检测iOS 6和所有次要版本?

我之前使用过的所有正则表达式都非常简单,现在我正在尝试让这个正则表达式正常工作,但却一直碰壁。不幸的是,PHP解析器没有给出任何错误提示!

我知道我做错了什么,因为我在我的笔记本电脑上运行火狐浏览器时还能匹配以下代码。

如果有人能指导我正确的方向,我将不胜感激,我无法弄清楚自己做错了什么。

$subject = $_SERVER['HTTP_USER_AGENT'];
$pattern = '~^(?:(?:(?:Mozilla/\d.\d\s*()+|Mobile\s*Safari\s*\d+.\d+(.\d+)?\s*)(?:iPhone(?:\s+Simulator)?|iPad|iPod);\s*(?:U;\s*)?(?:[a-z]+(?:-[a-z]+)?;\s*)?CPU\s* (?:iPhone\s*)?(?:OS\s*\d+\d+(?:\d+)?\s*)?(?:like|comme)\s*Mac\s*O?S?\s*X(?:;\s*[a-z]+(?:-[a-z]+)?)?)\s*)?(?:AppleWebKit/\d+(?:.\d+(?:.\d+)?|\s*+)?\s*)?(?:(KHTML,\s*(?:like|comme)\s*Gecko\s*)\s*)?(?:Version/\d+.\d+(?:.\d+)?\s*)?(?:Mobile/\w+\s*)?(?:Safari/\d+.\d+(.\d+)?)?.*$~';

if (preg_match($pattern,$subject))
{
    echo "match";
}

var_dump( $_SERVER['HTTP_USER_AGENT']); 输出什么? - nickb
@nickb 当然要看我使用的设备/浏览器是什么,但在我的笔记本电脑上使用Firefox时:string(83) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:15.0) Gecko/20100101 Firefox/15.0.1" 这不应该匹配! - nmford
2
显然,问题在于正则表达式有误 - 它确实匹配了该用户代理,但明显这不是正确的行为。 - nickb
@nickb 哎呀,我以为那个人在回复中的细节和说明都是正确的! - nmford
@nickb 特别是因为该用户已将其标记为正确答案。 - nmford
2个回答

3

试试这个替代方案:

^(?:(?:(?:Mozilla/\d\.\d\s*\()+|Mobile\s*Safari\s*\d+\.\d+(\.\d+)?\s*)(?:iPhone(?:\s+Simulator)?|iPad|iPod);\s*(?:U;\s*)?(?:[a-z]+(?:-[a-z]+)?;\s*)?CPU\s*(?:iPhone\s*)?(?:OS\s*\d+_\d+(?:_\d+)?\s*)?(?:like|comme)\s*Mac\s*O?S?\s*X(?:;\s*[a-z]+(?:-[a-z]+)?)?\)\s*)?(?:AppleWebKit/\d+(?:\.\d+(?:\.\d+)?|\s*\+)?\s*)?(?:\(KHTML,\s*(?:like|comme)\s*Gecko\s*\)\s*)?(?:Version/\d+\.\d+(?:\.\d+)?\s*)?(?:Mobile/\w+\s*)?(?:Safari/\d+\.\d+(\.\d+)?.*)?$

演示: http://gskinner.com/RegExr/?32eou

更通用的解决方案: http://code.google.com/p/php-mobile-detect/


警告:preg_match() [function.preg-match]:编译失败:字符类中的范围顺序错误,偏移量为243。 - nmford
1
脚本现在可以解析,但它仍然匹配我的笔记本电脑上的Firefox,这是不应该的。开始考虑也许我应该自己组合一些更简单的东西! - nmford
1
@nmford:由于Mozilla匹配Firefox,并且其他所有内容都是可选的...你应该使用原子组。更好的选择是不要重复造轮子:http://code.google.com/p/php-mobile-detect/。 - Alix Axel
在这里看到过它的提及,并且自那以后一直在使用它们! - nmford
2
@AlixAxel 我已经更新了演示。现在它可以正常运行了。我注意到你答案中的原始剪切/粘贴正则表达式有一些元字符被省略了。 - Stephan
显示剩余5条评论

3

正则表达式出现错误。由于SO字符转义系统的原因,一些元字符已经消失了。

以下是更新后的问题PHP代码:

$subject = $_SERVER['HTTP_USER_AGENT'];
$pattern = '~^(?:(?:(?:Mozilla/\d\.\d\s*\()+|Mobile\s*Safari\s*\d+\.\d+(\.\d+)?\s*)(?:iPhone(?:\s+Simulator)?|iPad|iPod);\s*(?:U;\s*)?(?:[a-z]+(?:-[a-z]+)?;\s*)?CPU\s*(?:iPhone\s*)?(?:OS\s*\d+_\d+(?:_\d+)?\s*)?(?:like|comme)\s*Mac\s*O?S?\s*X(?:;\s*[a-z]+(?:-[a-z]+)?)?\)\s*)?(?:AppleWebKit/\d+(?:\.\d+(?:\.\d+)?|\s*\+)?\s*)?(?:\(KHTML,\s*(?:like|comme)\s*Gecko\s*\)\s*)?(?:Version/\d+\.\d+(?:\.\d+)?\s*)?(?:Mobile/\w+\s*)?(?:Safari/\d+\.\d+(?:\.\d+)?.*)?$~';

if (preg_match($pattern,$subject))
{
    echo "match";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接