一篇文章掌握正则表达式

275 阅读3分钟

本文是基于几位前辈的文章进行撰写的

参考文章:就因为这三个知识点,我彻底学废了”正则表达式“ - 掘金 (juejin.cn)

首先认识元字符

. \d \D \w \W

.匹配单个任意字符
\d匹配数字
\D匹配非数字
\w匹配字母、数字、下划线
\W匹配非字母、数字、下划线。(*!等特殊字符)

\b

\b和\B都有点难记。

\b是会按照英文单词的划分方式,将一串字符串中划分为每个单词(不一定是真正的单词)。比如'this is your_xp01',其中this is 和your_xp01都被划分为独立的单词(常用)

\B则是划分字母数字之间,但是不包含边界。比如"this",其中t \B h \B i \B s,只有中间被划分了,而两边是划分单词的,就不计入。(不常用)

{}匹配次数

统一记住{}就行了

{x}为x次,{min,max}为min到max之间次,{min,}为min到无限次

0次到多次,用{0,},也就是*

1次到多次,用{1,},也就是+

0次或1次,用{0,1},也就是?

所以匹配任意长度的字符串的组合是

/.?/
也可以是/.{0,}/

[]限定字符

有时候要限定匹配到某几个特定的字符,就可以用[]括起来,比如要指定匹配abc其中一个字符,就可以[abc],或者匹配小写字母[a-z]

字符构成

一段字符,不仅仅是由可见的字符构成,还有不可见的字符间隙构成,例如一个"hello"的构成:

'hello' === '' + 'h' + '' + 'e' + '' + 'l' + '' +  'l' + '' + 'o' + ''

image.png

图像来源于@前端胖头鱼

关于边界,^$的位置(^在[]条件中表示取反),如图:

image.png

对于这个字符,我们要想截取出每个单词来,就可以用到\w匹配单词

"let's start vue".match(/\w+[']?\w+/g) 
//["let's", 'start', 'vue']

查找顺序

以下这些都是非捕获查询,也就是不会包含查找条件,例如查找一个标签的内容,不要包含标签;如果需要包含,那么只需要/xx/即可。

向前查找(?=xx)

匹配xx结尾的内容,不含xx。比如我们需要查找一串字符中的图片的名字,"afakj asfa asf asfdj fja kfj.jpg",我们只需要kfj这个名字,那就要先匹配到.jpg再匹配前面的字符

一般的用法是这样的:

"afakj asfa asf asfdj fja kfj.jpg".match(/\w+.jpg/g) 
//["kfj.jpg"]

但是会戴上匹配条件,如果不想要匹配条件,可以写成以下:

"afakj asfa asf asfdj fja kfj.jpg".match(/\w+(?=.jpg)/g) 
//["kfj"]

前面不能有(?!=xx)

前面不能有xx

向后查找(?<=xx)

匹配xx开头的内容,不含xx。比如我们想匹配一串网址后面的域名,"https://www.baicu.com",而只需要www.baidu.com

一般的写法是这样的,但是会戴上前缀

'http://www.baidu.com'.match(/http:\/\/.+/g) 
//["http://www.baidu.com"]

如果不需要前缀,可以写成以下:

'http://www.baidu.com'.match(/(?<=(?:http:\/\/)).+/g) 
//["www.baidu.com"]
//?:是为了把匹配到的不加入内存,提高代码运行速度,不用也是可以的
'http://www.baidu.com'.match(/(?<=http:\/\/).+/g) 

不过我还是一直不明白?:的用法

后面不能有(?<!xx)

后面不能有xx

非贪婪匹配

正则默认是贪婪匹配,即会匹配尽可能多的内容,如<span>第一段文字</span><span>这是二段文字</span>.match(/<\w+>.+</\w+>/g),本来匹配到第一个span结束就满足条件了,但是因为贪婪匹配,会尝试继续向后匹配,直到不满足条件的前一个,结果是<span>第一段文字</span><span>这是二段文字</span>

开启非贪婪匹配,只需要在结束条件的前面加?就可以了

"<span>第一段文字</span><span>这是二段文字</span>".match(/<\w+>.+?<\/\w+>/g)
//["<span>第一段文字</span>", "<span>这是二段文字</span>"]