前言
正则表达式是很重要的。几乎每一门语言都会去支持正则表达式,ECMAScript是通过RegExp类型来支持正则的。正则其实很常用,比如我们的路由是怎么去相应的匹配页面、在一段文字中提取我想要的文字等等都需要去使用正则。
let pattern = /at/gi
创建正则对象可以用字面量形式或者RegExp构造函数形式
也就是我们上面定义的这种
let pattern = /at/gi
元字符
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。如\n匹配换行符
^ 匹配输入字符串的开始位置
$ 匹配输入字符串的结束位置
* 匹配前面的子表达式0次或多次
+ 匹配前面的子表达式1次或多次
?匹配前面的子表达式0次或1次
. 匹配换行符之外的任何单个字符
x|y 匹配x或y
[xyz] 匹配所包含的任意一个字符
[^xyz] 匹配未包含的任意一个字符
[a-z] 匹配a-z的任意一个小写字母
\d 匹配一个数字字符 等价于 [0-9]
\D 匹配一个非数字字符 等价于[^0-9]
let pa = /[bc]at/i 匹配第一个"bat"或"cat" ,忽略大小写
let pa = /\[bc]at/i 匹配第一个"[bc]at" 忽略大小写
let pa = /.at/gi 匹配所有以"at"结尾的三字符组合,忽略大小写
let pa = /\.at/gi 匹配所有".at"忽略大小写
要想使用元字符,必须进行转义。
这种方式,传入的两个参数都是字符串
let pat = new RegExp("[bc]at","i")
元字符需要二次转意 \转义为 \\
,如 \n \\n
字面量模式 对应的字符串
/\[bc\]at/ "\\[bc\\]at"
/\.at\ "\\.at"
/name\/age/ "name\\/age"
/\d.\d{1,2}/ "\\d.\\d{1,2}"
/\w\\hello\\123/ "\\w\\\\hello\\\\123"
这些属性可以全面了解正则表达式的信息,但是实际开发并不常用。比如我不需要知道正则表达式中是否使用了g。
exec()
和 test()
exec()
参数:要应用模式的字符串
需求:内部的匹配项"and baby",内部的 "and dad" 或 "and dad and bay"
let txt ="mom and dad and baby"
// 注意空格
let pattern = /mom( and dad( and baby)?)?/gi
let match = pattern.exec(txt)
// ['mom and dad and baby', ' and dad and baby', ' and baby', index: 0, input: 'mom and dad and baby', groups: ?developer/article/2208668/undefined]
let arr = [1]
arr.input = "test" // [1, 2, input: 'test']
全局匹配究竟是什么意思?即使exec(),使用了全局匹配,返回的结果还是相同的啊?
let text = "cat, bat, sat, fat"
let nogpattern = /.at/
// ['cat', index: 0, input: 'cat, bat, sat, fat', groups: ?developer/article/2208668/undefined]
nopattern.exec(text)
// ['cat', index: 0, input: 'cat, bat, sat, fat', groups: ?developer/article/2208668/undefined]
let havegpattern = /.at/g
havegpattern.exec(text)
这是因为需要再次调用exec(),它才会再向下寻找。这时候才能体现出 g
的作用
没使用 g
let text = "cat, bat, sat, fat"
let nog = /.at/
nog.exec(text) // ['cat', index: 0, input: 'cat, bat, sat, fat', groups: ?developer/article/2208668/undefined]
console.log(nog.lastIndex) // 0 最后匹配到的索引
nog.exec(text) //['cat', index: 0, input: 'cat, bat, sat, fat', groups: ?developer/article/2208668/undefined]
console.log(nog.lastIndex) // 0
使用 g
let text = "cat, bat, sat, fat"
let haveg = /.at/g // ['cat', index: 0, input: 'cat, bat, sat, fat', groups: ?developer/article/2208668/undefined]
console.log(haveg.lastIndex) // 0
haveg.exec(text) // ['bat', index: 5, input: 'cat, bat, sat, fat', groups: ?developer/article/2208668/undefined]
console.log(haveg.lastIndex) // 8
只查找从lastIndex开始和以后的字符串
let text = "_aa_a"
let pattern = /_a+/y
pattern.exec(text) // ['_aa', index: 0, input: '_aa_a', groups: ?developer/article/2208668/undefined]
y
但是 我们想匹配aa 或 a 返回的就是null。因为从lastIndex(0)开始寻找 。它找的字符串是 ["_","_a","_aa","_aa_","_aa_a"]
也就是从下标为0开始的所有排列租户,
let text = "_aa_a"
let pattern = /a+/y
pattern.exec(text) //null
console.log(text.lastIndex) // 0
如果重新定义 pattern
的 lastIndex
则就可以找到
pattern.lastIndex = 1
pattern.exec(text) // pattern.exec(text) //null
g
而如果是g,则找的是["_","_a","_aa","_aa_","_aa_a","a","aa","aa_","aa_a","a","a_","a_a","_","_a","a"]
也就是所有可能出现的排列组合。
test()
这个方法用于校验,模式是否匹配。返回true 或 false
let a = "_aa_a"
let pattern = /_a+/g
pattern.test(a) // true
toLocaleString() 和 toString()
let pattern = new RegExp("\\[bc\\]at","gi");
pattern.toString() // '/\[bc\]at/gi'
pattern.toLocaleString() // '/\[bc\]at/gi'
valueof()
返回正则表达式本身
通过以下属性可以提取出与exec()和test()执行的操作相关信息
let text = "this has been a short summer";
let pattern = /(.)hort/g
if(pattern.test(text)){
console.log(RegExp.input); // this has been a short summerh'n'm'n
console.log(RegExp.$_); // 同上
console.log(RegExp.leftContext); // tis has been a
console.log(RegExp["$`"]) // 同上
console.log(RegExp.rightContext); // summer
console.log(RegExp.lastMatch); // short
console.log(RegExp.lastParen); // s
}