本文是基于几位前辈的文章进行撰写的
参考文章:就因为这三个知识点,我彻底学废了”正则表达式“ - 掘金 (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' + ''
关于边界,^$的位置(^在[]条件中表示取反),如图:
对于这个字符,我们要想截取出每个单词来,就可以用到\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>"]