本文是JS正则表达式完整教程(略长)的学习笔记。
正则表达式的创建
- const re = /abcd/
- const re = new RegExp(‘abcd’)
其中,abcd表示要匹配的模式。
一个字符匹配多次和从多个字符中匹配一个
一个字符匹配多次
要想把一个字符匹配多次,我们可以使用大括号中包含范围的方法来表示,形式如下:
const re = /abc{1,100}d/
这个正则就表示,将c匹配1到100次。也就是说,这个正则既能匹配到像abcd这样的字符串,也能匹配到像abccd甚至更多的c的字符床,只要c的个数不超过100个。其中的1和100我们可以根据需要,随意替换成我们需要的范围,下面为了方便表示说明,我们用
{m,n}
来表示说明。m表示下限,n表示上限,当只出现m不出现n时
{m,}
表示对应的字符串出现m以上的次数,当只出现m时{m}
表示对应的字符出现m次。另外,还有三个对应的简易用法,用符号来表示对应的范围。1.?等价于{0,1}。
- +等价于{1,}。即对应的字符串出现1次到正无穷次
- *等价于{0,}。即对应的字符串出现0到正无穷次。
多个字符中匹配一个
这种形式就是,我们想从多个字符中匹配一个。比如我们想匹配在一个字符串中匹配a,b,c,d,e。我们可以用如下方式,
[abcde]
这样,举个例子const re = /test[abcde]/
在这个正则表达式中,我们就可以匹配testa,testb,testc,testd,teste。
多个匹配模式
既然可以匹配一个或者多个字符,强大的正则照样可以匹配一个或者多个模式。实现形式是/p1|p2|p3/
其中p1,p2,p3就是三个独立的模式。
比如
1 | var regex = /good|nice/g; |
匹配的简易写法
当我们需要匹配多个字符中的一个时,我们可以用[abcdef···]
这样的方法来实现,但是不免显得比较啰嗦,所以我们需要一个简写模式。
当我们想匹配任意字母表中的一个时,我们可以用
[a-z]
,这样,我们就把所有小写字母都匹配了。相应的,当我们想匹配所有大写字母时,我们就写成[A-Z],这样,所有的大写字母就都匹配上了。接下来就是所有数字了,我觉得其实已经可以猜到怎么匹配所有的数子了吧,没错就是[0-9]。有的时候,我们还想匹配“-”符号,这个时候,可以把它放在开头或者末尾,这样就不表示范围了。当然还可以放在中间,但是需要加一个转义符号“\”。
我们有啥都想要的时候,也有啥都不想要的时候,当我们不想要时,就可以用
[^abc]
来表示了,这个也可以用范围表示法来表示。3.你以为范围表示法够简便了吧?其实不是,还有更简便的,接下来我们继续人事一下。
\d 等价于
[0,9]
,所有数字中的一个;\D等价于
[^0,9]
,表示除了数字外的一切;\w等价于
[0-9a-zA-Z]
,表示数字,字母以及下划线;\W等价于
[^0-9a-zA-Z]
,表示非单词字符。\s表示
[ \t\v\n\r\f]
。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。\S
是[^ \t\v\n\r\f]
。 非空白符。·通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外。
现在,你想匹配任意字符时,就可以用[\d\D]
、
[\w\W]、
[\s\S]和
[^]`中任何的一个来实现了。
贪婪匹配和惰性匹配
贪婪匹配就是尽可能多的匹配,有多少收多少;惰性匹配则是匹配到第一个后,就不动了,任你千军万马,我也不去管了。
默认的都是贪婪匹配,要想实现惰性匹配,只需要在匹配的次数后面添加一个“?”就可以了。
在某个位置匹配
^
匹配开头,在多行匹配中匹配行开头。
$
匹配结尾,在多行匹配中匹配行结尾。
\b
是单词边界,具体就是\w
和\W
之间的位置,也包括\w
和^
之间的位置,也包括\w
和$
之间的位置。
\B
非单词\b的反面意思,非单词边界。
(?=p)
,其中p
是一个子模式,即p
前面的位置。
而(?!p)
就是(?=p)
的反面意思
在正则中使用括号
1.分组
我们已经学习过如何匹配一个字符出现一次或者多次的情况,但是如何匹配多个字符出现一次或者多次的情况呢?
这个我们需要用到括号了,只需要将需要匹配且多次出现的符号用括号括起来,就可以实现了。如下:const re = /a(bc){0,6}/
这样,就可以匹配bc出现多次的情况了,如字符床abcbcd。
2.结合之前多个字符的经验,多个模式也是可以用括号来实现了。如: const re = /a(b|c|d)/
这样,就可以匹配ab或者ac或者ad了。
3.与match或者exec结合,提取数据。
match
返回的一个数组,第一个元素是整体匹配结果,然后是各个分组(括号里)匹配的内容,然后是匹配下标,最后是输入的文本。(注意:如果正则是否有修饰符g
,match
返回的数组格式是不一样的)。
另外也可以使用正则对象的exec
方法,也可以使用构造函数的全局属性$1
至$9
来获取。
4.替换
比如,想把yyyy-mm-dd格式,替换成mm/dd/yyyy怎么做?
1 | var regex = /(\d{4})-(\d{2})-(\d{2})/; |
其中replace
中的,第二个参数里用$1
、$2
、$3
指代相应的分组。等价于如下的形式:
1 | var regex = /(\d{4})-(\d{2})-(\d{2})/; |
也等价于:
1 | var regex = /(\d{4})-(\d{2})-(\d{2})/; |
3.反响引用
除了使用相应API来引用分组,也可以在正则本身里引用分组。但只能引用之前出现的分组,即反向引用。
还是以日期为例。
比如要写一个正则支持匹配如下三种格式:
2016-06-12
2016/06/12
2016.06.12
最先可能想到的正则是:
1 | var regex = /\d{4}(-|\/|\.)\d{2}(-|\/|\.)\d{2}/; |
其中/
和.
需要转义。虽然匹配了要求的情况,但也匹配”2016-06/12”这样的数据。
假设我们想要求分割符前后一致怎么办?此时需要使用反向引用:
1 | var regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/; |
注意里面的\1
,表示的引用之前的那个分组(-|\/|\.)
。不管它匹配到什么(比如-),\1
都匹配那个同样的具体某个字符。
我们知道了\1
的含义后,那么\2
和\3
的概念也就理解了,即分别指代第二个和第三个分组。
和正则匹配使用的相关API
search
用来搜索指定的字符串或者指定的正则。会返回匹配到的字符串或者正则表达式的位置。匹配不到时会返回-1.
test
检测字符串是否匹配某个模式,如果匹配返回true,否则返回false。
match
在字符串内检索指定的值或者正则表达式,返回匹配到的数组,如果没有匹配到则返回null。
exec
方法用于检索字符串中的正则表达式的匹配。如果字符串中有匹配的值返回该匹配值,否则返回 null。
split
用于将一个字符串按照某个字符或者正则分割成数组。
replace
方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
正则表达式中的修饰符
g
全局匹配,即找到所有匹配的,单词是global
i
忽略字母大小写,单词ingoreCase
m
多行匹配,只影响^
和$
,二者变成行的概念,即行开头和行结尾。单词是multiline