我在jQuery源代码中遇到了这个正则表达式:
...
rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
...
我想知道为什么它相当复杂。我对第二部分背后的原因特别感兴趣:
(?:.*? rv:([\w.]+))?
我做了一些研究,但我无法弄清楚正则表达式的这部分是什么。
(?:) to match but not capture
.*? any amount of any character
rv: something literal
([\w.]+) one or more word characters or a dot
? appear 0 or 1 time
特别是,最后?
对我来说没有多大意义。如果存在或不存在由第二部分定义的子字符串,则整个第二部分匹配。通过一些试验和错误,正则表达式似乎与以下不同:
/(mozilla)/
有人可以说明正则表达式的第二部分应该做什么吗?它有什么约束;什么字符串失败,通过/(mozilla)/
或反过来?
答案 0 :(得分:4)
两个正则表达式匹配相同的字符串,但会在其捕获组中存储不同的信息。
表示字符串:mozilla asdf rv:sadf
/(mozilla)(?:.*? rv:([\w.]+))?/
$0 = 'mozilla asdf rv:sadf'
$1 = 'mozilla'
$2 = 'sadf'
/(mozilla)/
$0 = 'mozilla'
$1 = 'mozilla'
$2 = ''
答案 1 :(得分:2)
首先,我想澄清一下之间的区别:
.*? - non-greedy match
.* - greedy match
非贪婪将匹配可能的最小字节数(给定搜索字符串的其余部分),贪婪的字符将匹配最多。
给出字符串:
mozilla some text here rv:abc xyz
正则表达式将返回'mozilla'和'abc'。但如果'rv:'不存在,正则表达式仍将返回'mozilla'。
答案 2 :(得分:2)
注意:我现在注意到这个答案可能有点超出了范围。我仍然会留下它以获取更多信息,但是如果你认为它太多了,请注意,我会删除它。
@arnaud是对的,它是获取版本的。使用表达式的Here is the code:
uaMatch: function( ua ) {
ua = ua.toLowerCase();
var match = rwebkit.exec( ua ) ||
ropera.exec( ua ) ||
rmsie.exec( ua ) ||
ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
[];
return { browser: match[1] || "", version: match[2] || "0" };
},
您可以看到该函数返回找到的版本,如果没有,则返回0
。对于某些浏览器而言,这可能是必需的,或者仅作为开发人员的附加信息提供。
该函数名为here:
browserMatch = jQuery.uaMatch( userAgent );
if ( browserMatch.browser ) {
jQuery.browser[ browserMatch.browser ] = true;
jQuery.browser.version = browserMatch.version;
}
答案 3 :(得分:1)
([\w.]+)
内的(?:.*? rv:([\w.]+))
正在捕获,所以也许这个正则表达式用于获取过去的修订版号(但似乎当前jquery仅检查正则表达式是否匹配)。
答案 4 :(得分:0)
(pat)是用于匹配完整包含模式的模式分隔符。 (?:pat)是上面的否定,就像字符集括号[^]是[]的否定一样。在javascript中,!会出现否定 。匹配任何字符,*是匹配的量词,并且在较新的正则表达式引擎中也可以写为{0,}(但这三个附加字符可能会导致键盘更早死亡!) ?冗余匹配量词:可以匹配零次或一次 rv:.... literal rv
另一个子匹配,可以在父匹配中匹配零次或一次 ([\瓦特] +))? [\ w。] ...字符集,带有转义的w“\ w”:任何字母数字字符,又名[a-zA-Z0-9_]后跟一个文字点,每个匹配量词+,可能出现一个或多个次
要对模式匹配的含义进行逆向工程:只需在文本编辑器中从左侧开始进行评估,并用随机文字替换字母,这些文字会浮现在脑中并且每个子表达式都匹配。 然后退后一步,思考正则表达式可能是什么。