3

我在 Javascript 中使用正则表达式来嗅探用户代理字符串。下面是一些伪代码:

is_not_tablet_bool = /android.+mobile/i.test(navigator.userAgent.toLowerCase());
switch(true)
{
     case (is_not_tablet_bool):
         return true;
     break;
}

我正在尝试制作一个正则表达式,它会做一些与上述相反的事情,即

  1. 确保 'android' 关键字出现在字符串中,同时
  2. 确保字符串中没有“mobile”关键字

感谢预期的帮助。

4

2 回答 2

6

负前瞻

正则表达式有一个称为负前瞻的结构,它匹配正则表达式中的字符串而不捕获前瞻部分:

你的正则表达式应该这样写:

/android(?!.*mobile)/i

这将匹配任何包含单词android且后跟单词mobile且忽略大小写的字符串。这也意味着您可以删除toLowerCase呼叫。

加法:负后视

如果您只需要匹配其中包含单词android但缺少移动设备(之前或之后)的字符串,则可以使用负前瞻和后瞻的组合。

/(?<!mobile.*)android(?!.*mobile)/i

但问题是Javascript 不支持负面的lookbehinds。因此,您必须采用不同的技巧来帮助您确定这种情况。

有几种可能性,其中以下似乎是最有趣的(最后一个很有用):

  1. 替换之后将失败的匹配负字符串:

    var nav = navigator.userAgent.replace(/mobile.*android/, "fail" );
    return /android(?!.*mobile)/i.test(nav);
    
  2. 使用两个前瞻。一个在普通字符串上,另一个在反向字符串上,同时还有一个反向的正则表达式:

    var nav = navigator.userAgent;
    var after = /android(?!.*mobile)/i.test(nav);
    var before = /diordna(?!.*elibom)/i.test(nav.split("").reverse().join(""));
    return before && after;
    
  3. 简单是关键。两个简单的正则表达式也可以解决问题:

    var nav = navigator.userAgent;
    return /android/i.test(nav) && !/mobile/i.test(nav);
    

注意:我不确定您的代码是否是实际代码,因为如果是,我强烈建议您重新考虑使用 switch(true) 语句并将其替换为
return is_not_tablet_bool;.

于 2012-11-19T17:30:54.777 回答
0

我不认为使用正则表达式会使这项任务变得更容易。String.indexOf(...)我将使用以下方法简单地检查这些字符串的包含和排除:

function isNotAndroidMobile(userAgentString) {
  var ua = userAgentString.toLowerCase();
  return (ua.indexOf('android')>=0) && (ua.indexOf('mobile')===-1);
}
于 2012-11-19T17:51:12.323 回答