以【执果索因】法理解jQuery源码出现的正则表达式
在学习jQuery源码的过程中,碰到了好多的正则表则表达式,由于当时时间有限,也是为了理清思路,只是参照着注释,知道了通过正则匹配后得到的结果,对于其书写的形式并没有过多的探讨。本篇文章,我们就仔细探讨一下jQuery源码中用到的正则表达式吧。
首先,我们默认您对javascript基础的正则表达式有一定的了解。如果您在基础这块需要帮助,可以翻看我之前写的关于JavaScript正则表达式的文章,进行基础性的学习。
总的来说,jQuery中的正则不算难,也很好理解。在介绍jquery正则之前,我们先介绍一个比较难一点的正则数字千分位分隔符。对于这样一道经典的面试题,解决的方案很多,就我知道的有两种,至于具体的实现,请查看我之前写的文章《五、正则表达常用实例》,这里我们主要讲解一下使用正则表达式一行代码解决这个问题的方法。
function formatNumber(number){
return number.replace(/\d{1,3}(?=(\d{3})+(?:$|\.))/g, '$1')
}
这段正则表达式用到了正则的正向预查?=
和子项的只匹配不捕获?:
的机制。如果你对这两个概念不是很熟悉的话,那就翻阅一下我之前写的文章吧。
一、jQuery源码中的正则表达式
1、匹配(单标签+字符串)和(#id)的正则(rquickExpr)
rquickExpr
这个正则定义在 jquery(v2.0.3)中的line:75
,在jQuery原型方法init
使用line:116
。
var rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/
match = rquickExpr.exec( selector );
之前的文章《三、(补充)jQuery源码中init方法详解》有过对这一块返回值的分析,如果您感兴趣,您可以看一下。
也可以根据注释,
// A simple way to check for HTML strings
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <)
知道这个正则主要匹配的下面两种结果:
$('#div1')
$('<p>hello')
那么下面我们就拿着这个结果来分析一下上面的正则表达式。
1、对于整体只匹配不捕获
我们可以看到,正则表达式的开头有?:
,说明,我们会对大正则不进行匹配。您可以参照下面的这段代码来看一下这样匹配模式的作用。
var rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/
console.log(rquickExpr.exec('#id'))
// ["#id", undefined, "id", index: 0, input: "#id", groups: undefined]
var rquickExpr1 = /^(\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/
console.log(rquickExpr.exec('#id'))
// ["#id", "#id", undefined, "id", index: 0, input: "#id", groups: undefined]
查看运行结果,我们就明白?:
的用途了。
2、匹配id的部分
var reg = /^#([\w-]*)$/
这部分是用来匹配$('#id')
这种情况的,比较简单,不过根据这个定义,$('#-')
可以匹配,执行下面的代码,返回为true,说明确实可以,虽然我不知到在什么地方会用到这一点。
var rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/
console.log(rquickExpr.test('#-')) // true
3、匹配$('<p>hello')的部分
var str = '<p>hello'
var reg = /^(?:\s*(<[\w\W]+>)[^>]*)$/
console.log(reg.exec(str))
// ["<p>hello", "<p>", undefined, index: 0, input: "<p>hello", groups: undefined]
您需要注意第二个^
是去反的意思,其他的还好理解。
2、匹配单标签正则 rsingleTag
rsingleTag
依然是在jQuery中实例方法init
中使用,定义在line:78
,使用在line:134
。
var rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/
此正则主要匹配下面几种情况
<p>
<p/>
<p></p>
<p/></p>
拿着上面分析得到的结果,我们再来看这个正则,就比较轻松简单了。
jQuery源码中正则表达式很多,此处不能一一穷尽,持续更新中.....