写在前面
正则表达式很容易忘记,因此看了一篇小册子总结了一些基本的东西便于日后查看
正则表达式是一种匹配模式,要么匹配字符,要么匹配位置。精准匹配没有多大的意义,真正的意义在于实现模糊匹配。 模糊匹配又分纵向匹配和横向匹配
- 横向模糊匹配
横向模糊匹配表示一个位置上匹配的字符个数是不固定的,比如2{m,n}表示连续有m到n个2最少m个,最多n个。用大括号来表示,比如/ab{2,5}c/表示匹配这样一个字符串:第一个字符是a,第二个字符是2-5个字符b,最后一个是字符c。第一个字符是“a”,接下来是2到5个字符“b”,最后是字符“c”。 - 纵向模糊匹配
纵向模糊匹配时,表示具体某一位的值是不确定的, 用中括号表示,比如/a[123]c/表示第一位是a,第二位是123中的某一个,第三个是c。注意中括号里面的123不用逗号隔开。美元符号表示匹配结尾。 - 三种模式
g:表示全局 i:表示不区分大小写,忽略字符串的大小写 m:表示多行模式,到达一行文本末尾会继续查找下一行中是否存在与模式匹配的项
匹配字符
1.1字符组
字符组虽然叫字符组,但是表示的是一个字符,如[123]是一个字符组,但是表示的字符123中的某一个。
1.2字符组的表示方法
-
范围表示法
比如[123456abcdeABCDEF],可以用[1-6a-eA-f],用连字符和省略来简写。因为连字符有特殊用途,那么要匹配“a”、“-”、“z”这三者中任意一个字符,该怎么做呢?不能写成[a-z],因为其表示小写字符中的任何一个字符。可以写成如下[-az]或[az-]或[a-z]。即要么放在开头,要么放在结尾,要么转义。总之不会让引擎认为是范围表示法就行了。
-
排除字符组,取反表示
如[^abc]表示出了abc之外的字符的字符,也叫反义字符组。另外/[1]/表示的是第一位,美元符号表示匹配最后一位 -
简写表示法
简写表示主要是‘三对一点’。三对分别是“\d和\D”,“\w和\W”,"\s和\S"
1 \d表示[0-9],\D就是取反[^0-9]
2 \w表示[0-9a-zA-Z],表示数字,字母大小写,下划线。\W就是取反[^0-9a-zA-Z]
3 \s是[ \t\v\n\r\f],表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。记忆方式:s是space character的首字母。\S是[^ \t\v\n\r\f]。
4 .就是[^\n\r\u2028\u2029]。通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外
中的每个点,都可以理解成占位符,表示任何类似的东西。
5 如果要匹配任意字符怎么办?可以使用[\d\D]、[\w\W]、[\s\S]和[^]中任何的一个。
2.1量词
量词也叫重复,知道{m,n}含义之后,还要记住一些简写形式,下面写出五种
2.2量词的表示方法
* {0,}表示出现任意次
+ {1,}表示至少出现一次
? {0,1}表示出现一次或零次
{m,} 表示至少出现m次
{m} 表示出现m次,等价于{m,m}
2.3量词匹配的贪婪匹配原则
比如/\w{2,4}/表示匹配2到4个空白符,可以匹配2,3,4个。但是匹配是贪婪的,能匹配四个就不匹配三个,能匹配三个就不匹配两个。
2.4量词匹配的惰性匹配原则
惰性匹配原则在量词后面加上一个问号,表示你满足了吗
{m,n}?
{m,}?
??
+?
*?
3.1分支模式
分支匹配是某一个模式有多个子模式中任选一种,纵向匹配与横线匹配匹配的是一个模式,个人觉得理解的难点是把纵向匹配与分支匹配区别开来。 如/a|b|c/表示的意思是可以匹配a,b和c。
3.2分支匹配案例
var regex = /cym|hds/;
var string = 12jeidjcymnnjhds;
console.log(string.match(regex));
var regex = /good|goodby/;
var string = 13goodby;
console.log(string.math(regex));
最后输出的结果是good,不是goodby,也就是说分支匹配结构是惰性的前面匹配上后面就不匹配了
匹配位置
一般匹配的都是字符,位置匹配的重视度往往没有那么高。
1.1位置匹配的字符
es5中位置匹配有六个瞄字符
1.1.1 ^和$
^(脱字符)匹配开头,在多行匹配中匹配行开头。
$(美元符号)匹配结尾,在多行匹配中匹配行结尾。
var result = "hello".replace(/^|$/g, '#');
console.log(result);
// => "#hello#"
多行匹配模式时,二者是行的概念,这个需要我们的注意:
var result = "I\nlove\njavascript".replace(/^|$/gm, '#');
console.log(result);
/*
#I#
#love#
#javascript#
*/
1.1.2 \b和\B
\b表示\w和\W,\w和^,\w和$之间的位置匹配。 例如
var reg = /\b/g;
var result = "[JS] Lesson_01.mp4".replace(/\b/g, '#');
console.log(result);
// => "[#JS#] #Lesson_01#.#mp4#"
比如上面的例子,把所有\B替换成"#":
var result = "[JS] Lesson_01.mp4".replace(/\B/g, '#');
console.log(result);
// => "#[J#S]# L#e#s#s#o#n#_#0#1.m#p#4"
1.1.3 (?=p)和(?!p)(?=p)
其中p是一个子模式,即p前面的位置。比如(?=l),表示'l'字符前面的位置,例如:
var result = "hello".replace(/(?=l)/g, '#');
console.log(result);
// => "he#l#lo"
而(?!p)就是(?=p)的反面意思,比如:
var result = "hello".replace(/(?!l)/g, '#');
console.log(result);
// => "#h#ell#o#"
复制代码二者的学名分别是positive lookahead和negative lookahead。中文翻译分别是正向先行断言和负向先行断言。ES6中,还支持positive lookbehind和negative lookbehind。具体是(?<=p)和(?<!p)。