正则表达式

匹配特殊字符或有特殊搭配原则的字符的最佳选择。

两种创建方式:

  • 直接量 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"]  非贪婪的