正则表达式(Regular Expression)是一种文本模式,包括普通字符和特殊字符(即元字符),使用单个字符串描述,匹配一系列匹配某个句法规则的字符串。
正则表达式:
创建方式
语法:
/pattern/flags
new RegExp(pattern [, flags])
RegExp(pattern [, flags])
flags | 含义 |
---|
g | 全局匹配;找到所有匹配,而不是在第一个匹配之后停止 |
i | 忽略大小写 |
m | 多行。将开始和结束字符(^和$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处。 |
u | Unicode; 将模式视为Unicode序列点的序列 |
y | 粘性匹配; 仅匹配目标字符串中此正则表达式的lastIndex属性指示的索引(并且不尝试从任何后续的索引匹配)。 |
s | dotAll |
-
正则表达式字面量,包含在斜杠之间
const regex = /ab + c/i;
-
调用RegExp对象的构造函数 或者 工厂符号创建正则表达式对象
语法: new RegExp(pattern [, flags])
let regex = new RegExp("ab+c");
// or
let regex1 = new RegExp(/ab+c/g);
// or
let regex2 = RegExp(/ab+c/i);
语法
- 简单模式, 直接匹配
let regex = RegExp(/abc/);
regex.test('abcd'); //true
除了上述的简单模式之外,都是特殊模式。
- 字符类别
字符 | 含义 |
---|
. | . 匹配除换行符 \n 之外的任何单字符。要匹配 . ,要使用转义字符 . 例如: /.n/将会匹配 “nay, an apple is on the tree” 中的 ‘an’ 和 ‘on’,但是不会匹配 ‘nay’ |
\ | 在非特殊字符之前表示下一个字符是特殊的,在特殊字字符前反斜杠可将特殊字符转义为字面量。 例如:/a*/ 表示匹配0个或多个a,但是/a\*/ 表示匹配a* 这样的字符串 |
\w | 匹配数字,字母和下划线,等价于[A-Za-z0-9_] |
\W | 匹配非数字字母和下划线的字符,等价于[^A-Za-z0-9_] |
\d | 匹配数字,相当于[0-9] |
\D | 匹配不是数字的字符 |
\s | 匹配一个空白符,包括空格/制表符/换页符和其他unicode空格例如:/\s\w*/ 匹配 “foo bar” 中的 ’ bar’ |
\S | 匹配一个非空白符,例如,/\S\w*/ 匹配 “foo bar” 中的 ‘foo’ |
- 全集就可以写成[\w\W]
- 字符集用[]括起来,[^]里面的
^
表示的是取反
- 量词
字符 | 含义 |
---|
* | 重复任意次,相当于{0, } |
+ | 重复1次或多次,相当于{1,} |
? | 重复0次或1次,相当于{0,1} |
x*? 或x+?等 | 紧跟在任何量词*, +, ?, 或者{} 后面,会使量词变成非贪婪的,尽可能少的匹配.上面三个都是贪婪模式,尽可能多的匹配 |
{n} | 重复n次 |
{n, } | 重复大于等于n次 |
{n, m} | 重复n到m次 |
// 前面有a说明得包含a字符,然后b重复{1, }次,也就是说后面的规则应用于前面的字符上
var regex = /ab+/;
regex.test('hab') //true
regex.exec('haba') //['ab',...]
regex.exec('habb') //['abb',...]
console.log('a', /\d+/.exec('123sad')); //['123' ...], 匹配‘123’
var b=new RegExp(/\d+?/);
b.exec('123sad'); // ['1'...],匹配'1'
var c= new RegExp(/\d*?/);
c.exec('123sad') //['',...], 匹配''
- 字符集合
字符 | 含义 |
---|
[xyz] | 字符集合,匹配集合中的任意一个字符,等价于[x-z] ,例如匹配"yang"中的’y’ |
[^xyz] | 补充字符集合,匹配任意不在字符集内的字符,等价于[^x-z] |
- 边界
字符 | 含义 |
---|
^ | 匹配输入的开始,例如:/^A/ 并不会匹配 “an A” 中的 ‘A’,但是会匹配 “An E” 中的 ‘A’. |
$ | 匹配输入的结束。/t$/ 不匹配’eater’,但是匹配’eat’. |
\b | 匹配一个零宽单词的边界,如一个字母与一个空格之间。如/\bno/匹配’at noon’中的’no’,/ly\b/ 匹配 “possibly yesterday.” 中的 “ly” |
\B | 匹配一个零宽非单词边界, 如两个字母之间或两个空格之间。如/ye\B/ 匹配 “possibly yesterday.” 中的 “ye” |
- \b与[\b]含义不一样,后者表示匹配一个退格符(backspace)
- 分组,分支和反向引用
字符 | 含义 |
---|
(x) | 匹配x并记住匹配项,可看作分组,此处括号为捕获括号 |
\n | n是一个正整数,一个反向引用,指向正则表达式中第 n 个括号(从左开始数)中匹配的子字符串 |
(?:x) | 匹配x但不记住匹配项,此处括号称为非捕获括号,匹配括号里整个字符串 |
x|y | 分支,匹配x或者y |
// 下例中`\2` 代表的是此处内容与第二个分组一致
'1111-22-33'.match(/(\d{4})-(\d{2})-\2/) //null,此处1111-22-33中22和33内容不一致
'1111-22-22'.match(/(\d{4})-(\d{2})-\2/) // ["1111-22-22", "1111", "22", index: 0, input: "1111-22-22", groups: undefined]
'1111-22-22'.match(/(\d{4})-(?:\d{2})-\2/) //null, 此处第二个分组未被记住
/(?:foo){1,2}/.exec('foooo bar foo bar') //["foo", index: 0, input: "foo bar foo bar", groups: undefined]
/foo{1,2}/.exec('foo bar foo bar')
// 输出结果相同,但是意义不同。上面的{1,2}匹配整个'foo', 下面的匹配的是最后一个'o', 见下例
/(?:fooo){1,2}/.exec('foooo bar foo bar') // ["fooo", index: 0, input: "foooo bar foo bar", groups: undefined]
/fooo{1,2}/.exec('foooo bar foo bar') // ["foooo", index: 0, input: "foooo bar foo bar", groups: undefined]
- 零宽断言
| 正向/预测先行/顺序/从左到右/y前面位置 | 负向/回顾后发/逆序/从右到左/y的后面位置 |
---|
肯定/正 | x(?=y) 匹配x仅当后面跟着y,正向肯定查找 | x(?<=y) 负向肯定查找 |
否定/负 | x(?!y) 匹配x仅当x后面不跟着y,正向否定查找 | x(?<!y) 负向否定查找 |
// 正向肯定
/(?=Sprat)Frost/.exec('SpratFrost') //null
/Frost(?=Sprat)/.exec('FrostSprat') // ["Frost", index: 0, input: "FrostSprat", groups: undefined]
//正向否定
/(?!Sprat)Frost/.exec('SpratFrostdsgd') // ["Frost..."]
/Frost(?!Sprat)/.exec('SpratFrostdsgd') // ["Frost..."]
//TODO: 逆向肯定
/(?<=Sprat)Frost/.exec('SpratFrost') //["Frost..."]
/Frost(?<=Sprat)/.exec('FrostSprat') // null
/Frost(?<=Sprat)/.exec('SpratFrost') //null
//TODO: 逆向否定
/Frost(?<!Sprat)/.exec('SpratFrostdsgd') // ['Frost...']
/Frost(?<!Sprat)/.exec('bvbvnFrostdsgd') // ['Frost...']
使用
与RegExp(exec和test方法)String(match, replace, search, split方法)结合使用。
这些方法在Javascript手册中有详细的解释。
方法 | 描述 |
---|
exec | 一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回null)。 |
test | 一个在字符串中测试是否匹配的RegExp方法,它返回true或false。 |
match | 一个在字符串中执行查找匹配的String方法,它返回一个数组或者在未匹配到时返回null。 |
search | 一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。 |
replace | 一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。 |
split | 一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的String方法。 |
扩展:
1./(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
2./(?<year>\d{4})-(?<month>\d{2})-\k<month>/
3. RegExp.$[_1-9]