在jQuery源码中,运用了大量的正则表达式,一开始在看的时候真的是一头雾水,尽管已经看过了JS高程里面的正则表达式。
今天,看了一篇深入理解正则表达式的文章,对正则表达式有了更深的认识,下面做一个回顾和总结。
正则表达式基础
JS正则表达式用来匹配字符串,即利用正则表达式来定一个规则,如果字符串符合这个规则,那么就可以匹配到。正则表达式的定义有两种方式:
第一种:(推荐的)
var reg = /[0-9]/; //匹配一个数字
var res = /[a-z]/ig; //匹配一个字母;后面的i表示忽略大小写;g表示全局匹配,即匹配到一个之后,就从下一个位置开始匹配
var reg = /\d/; //匹配一个数字
//正则中使用的转义字符很多,在内存中是\\d这样存储的
第二种:
//所以new 正则表达式时,是\\d的形式
var reg = new RegExp('\\d', 'g');
var reg = new RegExp('\\d', 'i');
正则表达式的方法常用的有以下几个:
reg.exec(str); //返回匹配到的字符串
reg.test(str); //判断字符串是否符合该正则规则,返回true或者false
我们也知道字符串也有与正则相关的方法:
str.replace(reg, 'A'); //用'A'来替换匹配到的字符串
str.match(reg); //返回匹配到的字符串,如果正则中有g标识,那么会匹配到所有的项
//有一个问题:
var reg = /\d\w\d/g;
var str = '4a8h7a7k3w8';
console.log(str.match(reg));
结果如下:
像8h7, 7k3等都没有匹配到,这是因为在正则表达式对象中有一个lastIndex属性,该属性表示当前匹配到哪一个位置了,如果正则表达式中有g标识,会沿着lastIndex的下一个位置开始继续进行匹配,这也只限于exec方法和test方法。那如果想要得到我们想的结果的话,可以这样做:
var reg = /\d\w\d/g;
var str = '4a8h7a7k3w8';
var arr = [];
var a;
while(a = reg.exec(str))
{
arr.push(a[0]);
reg.lastIndex -= 1;
}
最终匹配到5个分组
正则表达式进阶
在正则表达式中,用括号括起来的就表示一个分组,即最后得到的匹配中会有这个分组匹配得到的结果。
举个例子:
var reg = /\w(\d+)/;
var str = 'a38294';
reg.exec(str);
可以看到,得到的结果是一个长度为2的数组,第一个表示总的匹配结果,第二个则是分组匹配结果。
那么如何在加了括号的情况下,匹配了但是不会返回到结果里面呢?
这就用到正则中(?:)
之前在jQuery源码中看到了很多(?:)的情况,当时都觉得很复杂,不过现在再看,会觉得清晰很多。
(?:)的作用就是非捕获分组,即匹配时可以要匹配,但返回结果时,不会返回。
再比如上面那个例子:
var reg = /\w(?:\d+)/;
var str = 'a38294';
reg.exec(str);
这时结果中就只有一个匹配结果了。
而在jQuery源码中,这种用的很多。比如说:
快速匹配正则:
quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/
打眼一看,很麻烦,但分开看的话就好理解一些了。
- 先这样看(把括号都去掉)
/^[^#<]*<[\w\W]+>[^>]*$|#[\w\-]*$/
这个正则表达式分成两大部分,并且是或的关系。再打开
/^[^#<]*<[\w\W]+>[^>]*$/
/#[\w\-]*$/
可以看到,第一个是匹配html标签的,而且不能以#<开头,这个貌似与浏览器href 的Hash有关,根据注释是说防止修改网页hash值而被xss攻击;
第二个很明显,是匹配id选择器,即’#id’这种格式。
2.再把括号加上来看:
quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/
可以看到这有两个括号,表示返回结果中会有两个匹配分组,再加上一个总的分组匹配结果,可以知道最终的结果是一个长度为3的数组。
举两个例子:
var str = '#dshk';
var res = quickExpr.exec(str); //res为['dshk', undefined, 'dshk']
var str1 = '<li>dhjehu'
var res1 = quickExpr.exec(str1); //res1为 ['<li>dhjehu', '<li>', undefined]
到此,正则表达式这部分就整理到这里,当然,也不仅仅局限于今天说的几个操作符,或者说正则表达式的定义符。后期在jQuery源码中遇到还会再加, 希望共同进步!