正则表达式
匹配特殊字符或有特殊搭配原则的字符的最佳选择。
两种创建方式:
- 直接量 const reg = /abc/igm;
- 通过对象构造new出来 new RexExp(“ abc “, “ igm “);
你会发现在/……/这段正则后面会有三个奇怪的字母——>igm,他们就是
修饰符
修饰符可用于大小写不敏感的更全局的搜素:
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配。 (ignoreCase) |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 (global) |
m | 执行多行匹配。 |
m比较少用,在别的讲解也比较模糊
const str = "abcd\na"
const reg = /^a/g //匹配开头为a的a
str.match(reg) //["a"]
//如果我要把被换行的第二个a也匹配出来呢,那就要用到m
const str = "abcd\na" //经过\n换行符之后,第2个a在m看来算是第2行的行头,另起一行
const reg = /^a/gm //匹配开头为a的a
str.match(reg) //["a","a"]
表达式
表达式是一对[],一个方括号[]代表一位,方括号内写的是给这一位匹配的字段的规则
方括号用于查找某个范围内的字符:
表达式 | 描述 |
---|---|
[A-z] | 查找任何从大写A到小写z的所有字符(因为是由ASCⅡ码值排列的) |
[^A-z] | 查找任何不是从大写A到小写z的所有字符(^这个尖角号放在表达式里做逻辑非的作用) |
[abc] | 查找方括号之间的任何字符。 |
[0-9] | 查找任何从 0 至 9 的数字。 |
(x|y) | 查找任何以 | 分隔的选项。 |
元字符
字符 | 描述 |
---|---|
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 |
\B | 匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。 |
\d | 匹配一个数字字符。等价于 [0-9]。 |
\D | 匹配一个非数字字符。等价于 [^/d]。 |
\f |
匹配一个换页符。等价于 \x0c 和 \cL。 |
\n |
匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r |
匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\t\v\f\r\n ] |
\S | 匹配任何非空白字符。等价于 [^/s]。 |
\t |
匹配一个制表符。等价于 \x09 和 \cI。 |
\v |
匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
\w | 匹配字母、数字、下划线。等价于[A-Za-z0-9_]。 |
\W | 匹配非字母、数字、下划线。等价于 [^/w]。 |
\xn | 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,’\x41’ 匹配 “A”。’\x041’ 则等价于 ‘\x04’ & “1”。正则表达式中可以使用 ASCII 编码。 |
\uxxxx | 查找以十六进制数 xxxx 规定的 Unicode 字符。 |
量词
量词 | 描述 |
---|---|
n+ | 匹配任何包含至少一个 n 的字符串。 |
n* | 匹配任何包含零个或多个 n 的字符串。match方法返回的数组里会多一个“ ”空串 |
n? | 匹配任何包含零个或一个 n 的字符串。match方法返回的数组里会多一个“ ”空串 |
n{X} | 匹配包含X个n的序列的字符串 |
n{X,Y} | 匹配包含X到Y个n的序列字符串(默认贪婪匹配,能一次匹配Y个绝不匹配X个) |
n{X,} | 匹配至少包含X个n的序列字符串 |
^n | 匹配开头为n的字符串 |
n$ | 匹配结尾为n的字符串 |
?=n | 匹配后面紧接着n的字符串 |
?!n | 匹配后面没有紧接着n的字符串 |
那么看到最常用的^和$,有一个问题
const str = "abcabc"
const reg = /^abc$/g
str.match(reg);
这样的结果会是啥?
答案当然是null,/^abc$/g
——指的是以当前这个abc开头,并且以当前这个abc结尾的字符串匹配。
这种用法通常用于过筛重复的,限定死一个。
日常调用正则的方法
text()
reg.text(str);
它通过正则来搜索字符串,如果有符合正则要求的就返回true
没有就返回false
;
下面的例子搜索字符串中的字符 “e”:
var patt = /e/;
patt.test("The best things in life are free!"); //true
exec()
exec() 方法是一个正则表达式方法。
它通过指定的模式(pattern)搜索字符串,并返回已找到的文本。
如果未找到匹配,则返回 null。
下面的例子搜索字符串中的字符 “e”:
const reg = /ab/g
const str = "ababab"
//当在控制台执行reg.exec(str)时,只会返回["ab"],即使有修饰符g
//这样的结果能出现3次,第四次会出现null
console.log(reg.exec(str))
//["ab",index:0,input:"ababab"] ——>类数组
console.log(reg.exec(str)) //再执行一遍
//["ab",index:2,input:"ababab"] ——>index是匹配到规则后返回的索引位
match()
str.match(reg);
它用传进去的正则去判断自己的字符串,如果有符合正则要求的,会返回符合的字符串数组,比test()更直观
split()
str.split(reg);
通过正则表达式去拆分
const reg = "/\d/g"
const str = "ahds0jahsk0jdakdh"
str.split(reg) //["ahds","jahsk","jdakdh"]
replace()
意思就是替换呗,str.replace(A,B) ——>将A替换成B
const str = "aa"
str.replace("a","b") //"ba" ——>这里有个小问题,虽然看起来好像是会返回"bb",但是他并没有检测全局的能力
const reg = /a/g;
str.replace(reg , "b") //"bb" 和上面对比
再来一道有意思的小题,请把形如aabb的字符串变成bbaa形式
const reg = /(\w)\1(\w)\2/g
const str = "aabb"
str.replace(reg, "$2$2$1$1")
上面的$是指反向引用,$1指的是反向引用第一个子表达式,$2指的是反向引用的第二个子表达式
反向引用
()在元字符里面并没有起到太大的作用,但是如果放在正则表达式里——>/(a)/g 这种形式的话,就表示子表达式
在子表达式后面用反斜杠\加数字表示反向引用第几个子表达式的内容
const str = "aaabbb"
const reg = /(\w)\1\1(\w)\2\2/g
str.match(reg) //"aaabbb"
//这个时候如果使用reg.exec(str)的返回值,会把子表达式也会返回出来
//["aaabbb","a","b",index:0,input:"aaabbb"]
非贪婪匹配
正常正则都是遵循贪婪匹配的,能多匹配绝不少匹配。
当量词后面加?则会取消贪婪匹配。
const str = "aaaaa"
const reg = /a+/g
str.match(reg) //["aaaaa"] 贪婪的
const reg1 = /a+?/g
str.match(reg1) //["a","a","a","a","a"] 非贪婪的