检测Internet Explorer 11的正则表达式

10

我正在使用这个preg_match字符串

preg_match('/Trident/7.0; rv:11.0/',$_SERVER["HTTP_USER_AGENT"]

我希望能够检测到IE11,以便为其启用平板模式。但是它返回“未知分隔符7”。

我应该如何在不引起PHP报错的情况下实现这一点?


2
这只是告诉你它是IE11,而不是平板电脑甚至没有触摸功能的设备。很有可能访问该页面的IE11桌面用户比平板用户要多得多。如果为没有触摸屏的桌面用户启用平板模式会有什么后果? - Dave Methvin
1
我很惊讶没有人在我之前注意到这一点,但请不要使用浏览器检测。这是一个非常糟糕的习惯。相反,我建议您尝试响应式设计技术和特性检测来构建您的应用程序。顺便说一下,我曾经坚持过移动设备和桌面设备分别建立网站的做法,但这会导致大量的维护工作等问题。从移动端开始,再逐步扩展。比你想象的要容易得多。 - Chris Love
1
@ChrisLove,不行,因为谷歌使用浏览器检测,MSN和Microsoft.com也是如此。那我为什么不能呢? - ben
2
谷歌跳下金门大桥,你会跟进吗?你必须意识到像微软和谷歌这样的大型组织并不总是遵循最佳实践。我使用浏览器检测来确定访问者是否使用过时的浏览器。如果是,我会为他们提供一个无JavaScript的核心站点。但是现在的浏览器普遍都很强大。根据我近4年的移动客户端设计经验,我仍然建议采用响应式、移动优先的方法作为一种完整的解决方案。 - Chris Love
8个回答

14

这到底是一个正则表达式还是一个字符串?如果只是一个字符串,你可以使用strpos函数。

if (strpos($_SERVER['HTTP_USER_AGENT'], 'Trident/7.0; rv:11.0') !== false) {
    // your code
}

如果这是一个正则表达式,你必须转义特殊字符,例如/.

编辑:

在此答案的评论中可以看到该代码并不能正确地检测IE 11的所有情况。我没有真正测试它来匹配它,我只是调整了问题创建者的代码,使用strpos代替preg_match因为它被错误地应用。

如果你想要一种可靠的方法来检测IE 11,请查看其他答案。


不匹配我的IE字符串:Windows NT 6.3; WOW64; Trident/7.0; ASU2JS; rv:11.0 - Doug
1
这是一个访问日志。上述内容无效。这是从IE 11请求中获取的。172.16.0.85 - - [30/Jan/2015:16:15:01 +0000] "GET /wp-content/plugins/contact-form-7/includes/css/styles.css?ver=4.1 HTTP/1.1" 200 1103 "http://website-dev.uk.aaa.com/" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)" 0/3500 - shorif2000

10

用户代理字符串可能在不同的平台或设备上报告不同。请看这个链接:http://msdn.microsoft.com/en-au/library/ie/hh869301(v=vs.85).aspx

我发现了一种包含大部分IE11或以上版本所报告的用户代理的字符串模式(如果微软为新版本的IE再次更改其用户代理字符串,则该模式可能不再适用):

if (preg_match("/(Trident\/(\d{2,}|7|8|9)(.*)rv:(\d{2,}))|(MSIE\ (\d{2,}|8|9)(.*)Tablet\ PC)|(Trident\/(\d{2,}|7|8|9))/", $_SERVER["HTTP_USER_AGENT"], $match) != 0) {
    print 'You are using IE11 or above.';
}

6
我认为应该这样做。
if (preg_match("/Trident\/7.0;(.*)rv:11.0/", $_SERVER["HTTP_USER_AGENT"], $match) != 0) {}

因为有时候你可以看到像这样的用户代理:
Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; ASU2JS; rv:11.0) like Gecko

2

IE11有触屏版本和非触屏版本,这意味着Guilherme Sehn的答案对于触屏设备不起作用。

if(strpos($_SERVER['HTTP_USER_AGENT'], 'Trident/7.0; rv:11.0') !== false)

相反,使用以下内容:

if ( strpos($_SERVER['HTTP_USER_AGENT'], 'rv:11.0')     !== false
  && strpos($_SERVER['HTTP_USER_AGENT'], 'Trident/7.0;')!== false)
{
    echo "User is on IE11 touch / non-touch";
}

这是因为在“Trident”和修订版本号之间可以添加任意数量的参数。同样,如果您想检查它们是否在触摸上,只需对“Touch;”进行strpos搜索即可。

1

使用不在正则表达式字符串中的另一个字符是很好的选择,这样您就不必转义字符串,并且更容易阅读长字符串。因此,您可以使用作为分隔符:

preg_match('~Trident/7.0; rv:11.0~',$_SERVER["HTTP_USER_AGENT"])

另一个想法是使用stristr函数来查看一个字符串是否出现在另一个字符串中。
stristr($_SERVER['HTTP_USER_AGENT'],'Trident/7.0; rv:11.0')

0

您需要转义中间的斜杠/,以便在由斜杠包围的正则表达式中正常工作:

preg_match( '/Trident\/7.0; rv:11.0/', $_SERVER['HTTP_USER_AGENT'] );

您还可以使用preg_quote()来转义字符串中的所有特殊字符:

$regexp = sprintf( '/%s/', preg_quote( 'Trident/7.0; rv:11.0', '/' ) );
preg_match( $regexp, $_SERVER['HTTP_USER_AGENT'] );

http://www.php.net/manual/en/function.preg-quote.php


3
当你在整个正则表达式上使用 preg_quote 的时候,就应该意识到你其实不需要正则表达式了! - lonesomeday

0

Trident后面的/被视为分隔符。您可以对其进行转义:

preg_match('/Trident\/7.0; rv:11.0/',$_SERVER["HTTP_USER_AGENT"]

更好的做法是不要使用preg_match: 您并不需要它。您所要做的只是查找不变子字符串,这可以使用strpos来完成:
if (false !== strpos($_SERVER["HTTP_USER_AGENT"], '/Trident/7.0; rv:11.0/')) {

0

我会使用browscap项目来获取这些数据。它更快,更可靠。


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