快速掌握正则表达式 | 04 元字符真好玩
Posted 一百个Chocolate
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速掌握正则表达式 | 04 元字符真好玩相关的知识,希望对你有一定的参考价值。
在上一篇我们介绍了一些好玩的元字符,真是好玩,也没想到阅读量还是挺多的,也算是鸽了一段时间,今天我们继续来玩玩元字符,真好玩!
到底匹配多少个字符
在上一篇文章中,我们了解到了数字与非数字匹配、字母数字与非字母数字的匹配,以及后面提及的空白字符与非空白字符,然后进制的匹配问题。
那么,我们看看下面的例子:
let arr = ['https://yangchaoyi.vip/','Chocolate'];
let reg = /\\w\\w\\w\\w\\w:\\/\\/\\w\\w\\w\\w\\w\\w\\w\\w\\w\\w\\.\\w\\w\\w\\//g;
let res = arr.filter(item=>item.match(reg));
console.log(res); // ['https://yangchaoyi.vip/']
我们想要匹配一个网址,然后写下了如上述所示的正则表达式,看完之后有何感受?
还学个屁!
日常开个玩笑哈,既然说是这个元字符好玩,那么本次一定带来一些解放方案咯。
解决痛点
匹配一个或多个字符
在上文中,我们的痛点应该很清楚了,那就是多次、重复问题。
那么,我们现在来介绍 + 这个符号,在正则表达式中,它可以匹配一个或多个字符,直接上例子吧:
let arr = ['https://yangchaoyi.vip/','Chocolate'];
let reg = /\\w+:\\/\\/\\w+\\.\\w+\\//g;
let res = arr.filter(item=>item.match(reg));
console.log(res); // ['https://yangchaoyi.vip/']
ohhhhh,代码少了许多,是不是简单了不少呢。
当然,还有其它的匹配操作。
匹配零个或多个字符
直接再看一波例子吧:
let arr = ['https://yangchaoyi.vip/','Chocolate'];
let reg = /\\w*:\\/\\/[\\w\\.]*\\//g;
let res = arr.filter(item=>item.match(reg));
console.log(res); // ['https://yangchaoyi.vip/']
在这个例子中的不同点是:[\\w\\.]*
。
这个意思是对于 [a-zA-Z0-9_]
和 .
我们构造了一个字符集合,在字符集合后面有一个 *
,就代表这匹配零歌或多个字符,注意字符集和里面我们进行了转义,即\\.
,在这里的话,[\\w\\.]
的实际效果和[\\w.]
实际效果一样,但是转义一下会好一点,因为 .
可以匹配任意字符,所以用来匹配 .
看起来没多少区别。
不过像 . 这样的元字符如果呗包在字符集集合里面使用的时候,会被解释为普通字符,无需转义,因此其实写不写无所谓,但是为了自己清楚以及别人看得更懂,写一下会更好。
匹配零个或一个字符
接下来再来介绍相关的元字符 ?,它的作用在之前两个介绍之后应该显而易见了,直接看例子:
let arr = ['https://yangchaoyi.vip/','http://yangchaoyi.vip/','Chocolate'];
let reg = /\\w+s?:[\\w]?/g;
let res = arr.filter(item=>item.match(reg));
console.log(res); // ['https://yangchaoyi.vip/', 'http://yangchaoyi.vip/']
在这个例子中,我将 ? 放在 s 之后,想表达的意思是相匹配网址,不管是 http 的还是 https 的都可以,于是通过 ? 操作,匹配零次以及一次。
给定区间范围的匹配
在上文中,我们要么是匹配一个以上,或者起码要匹配一个,又或是匹配零个或一个。
我们发现这个范围是从 0 到 无穷大的,假设我们就想要某个区间范围的呢?
直接看例子吧:
let arr = ['#1','#22','#33','#4444','#55555','#666666','Chocolate'];
let reg = /#[\\w]6/g;
let res = arr.filter(item=>item.match(reg));
console.log(res); // ['#666666']
从上述例子来看,我们可以通过 来设定一个重复次数,可以是单个数值,当然也可以是区间,比如:
let arr = ['#1','#22','#3ab'];
let reg = /#\\d2,3/g;
let res = arr.filter(item=>item.match(reg));
console.log(res); // ['#22']
范围与无穷大
上述,我们设定了一个区间,但有时候我们右区间可能没有设定值,默认应该为无穷大,又应该是怎样呢?
直接看如下例子:
let arr = ['#1','#22','#33abc', '123123123123', '#123321'];
let reg = /#\\d2,/g;
let res = arr.filter(item=>item.match(reg));
console.log(res); // ['#22', '#33abc', '#123321']
这样,我们的区间范围变成了 [2, 无穷大]。
遇到一个问题
上述来看,我们都还是比较轻松的,掌握了一些匹配操作,但也只是解决了一些基础问题,我们来看下面这个例子:
let str = '<div>001</div><p>中间的文字</p><div>002</div>';
let reg = /<div>.*<\\/div>/g;
let res = str.match(reg);
console.log(res); // ['<div>001</div><p>中间的文字</p><div>002</div>']
诶,发现不对了乜有,我想匹配出两个的呢,为啥只有一个结果?
过度匹配
我们发现这里出现了过度匹配问题,其原因还是元字符这一块,因为像 * 和 + 我们之前介绍他们的区间右侧其实是无穷大的,属于是一种【贪婪型】的元字符,所以会一直匹配下去,找到最右边的 </div>
。
这显然不是我们本例想要的一个结果,不过我们在本例可以这样稍作修改:
let str = '<div>001</div><p>中间的文字</p><div>002</div>';
let reg = /<div>\\d*<\\/div>/g;
let res = str.match(reg);
console.log(res); // ['<div>001</div>', '<div>002</div>']
也还是可以匹配到两个结果,不过这并没有解决我们的问题。
贪婪—懒惰
对于【贪婪型】的元字符,相对的我们应该也会有【懒惰型】的,其实用法非常简单,就是加一个 ? 即可,我们直接上例子吧:
let str = '<div>001</div><p>中间的文字</p><div>002</div>';
let reg = /<div>\\d*?<\\/div>/g;
let res = str.match(reg);
console.log(res); // ['<div>001</div>', '<div>002</div>']
仅仅和之前相比多加了一个 ? 就解决了过度匹配问题,这样就不会因为过于贪婪匹配过多我们不想要的内容了,在实际应用中也许会遇到这两种情况,合理的使用他们会有不错的效果哦。
小结
不知不觉已经坚持输出第四篇博客了,中间还是停了一大段时间,继续努力更新完整个系列~
本小节内容到底就结束啦,感谢各位的阅读,我们期待下一篇吧。
以上是关于快速掌握正则表达式 | 04 元字符真好玩的主要内容,如果未能解决你的问题,请参考以下文章