导言
开发中会遇到很多的正则使用场景,特别是表单验证的时候,或是在阅读前辈的代码的时候(如果没有注释,读起来比写起来更艰难),而大部分的开发者写正则的机会很少,一般都是用一些公共类型做验证,但是这无法满足个性化的验证,所以熟悉正则,能够为大家节约很多的发量。顺便安利一个工具,能够根据正则生成图形化的流程图 正则图形化工具
创建Regexp对象
- 字面量。示例:
let reg = /\bis\b/g // g表示全局匹配 \b表示匹配一个零宽单词边界 这个正则表示匹配is这个单词
'you are beautiful,who are they'.replace(reg,'aaa') // "you aaa beautiful,who aaa they"
- 构造函数。示例:
let reg = new RegExp('\\bit\\b','gi') // 字符串中使用反斜线需要转义
'It is a apple,what is it?'.replace(reg,'aaa') // "aaa is a apple,what is aaa?"
常用修饰符
- g: 全文搜索,不添加则搜索到第一个停止。
- i: 是否忽略大小写,默认忽略,添加则不区分大小写。
- m: 多行搜索,针对于换行的字符串。
- 除此外还有u,y,s.可自行百度。
字符类型
- 原义文本字符(1,2,3,a,b,c)
- 元字符:有特殊含义的非字母字符(\t \n \b)文档
- * + - $ ^ [ ] { } \ . ( )
字符类,范围类 and
[] 表示一个字符类,如[1-9][a-z]就分别表示数字1到9,和字母a到z
'1230'.replace(/[^1-9]/g,'a') // "123a" ^表示取反
常用的预定义类
| 字符 | 等价类 | 含义 |
|---|---|---|
| . | [^\r\n] | 非回车符和换行符 |
| \d | [0-9] | 数字 |
| \D | [^0-9] | 非数字 |
| \w | [a-zA-Z_0-9] | 单词字符(数字下划线) |
| \W | [^a-zA-Z_0-9] | 非单词字 |
| \s | 空白符 | |
| \S | 非空白符 |
边界
- \b 单词边界
This is an apple.replace(/\Bis\b/g,'0') // Th0 is an apple
- ^ 在[]外表示开始
- $ 在[]外表示结束
let a = '!123!qaz!'
a.replace(/^!./,':')
":23!qaz!"
a.replace(/.!$/,':')
"!123!qa:"
数量规则
| 字符 | 含义 |
|---|---|
| ? | 0次或者1次,最多一次 |
| + | 最少1次 |
| * | 任意次 |
| {n} | n次 |
| {n,m} | n到m次 |
| {n,} | 至少n次 |
贪婪模式和非贪婪模式
正则表达式会尽可能多的去匹配,这被称为贪婪模式 ,可以加?做非贪婪模式的匹配
'12345678'.replace(/\d{3,6}/g,0)
"078"
'12345678'.replace(/\d{3,6}?/g,0)
"0078"
分组
()可以将将字面量进行分组,作为一个整体来使用数量控制
'a1b2c3d4'.replace(/([a-z]\d){3}/g,'X')
"Xd4"
'applepenappleben'.replace(/apple(b|p)en/g,"0") // | 表示或匹配
"00"
//反向引用 分组取参 按分组顺序可以对应 $1 $2 $3...
'2020-05-20'.replace(/(\d{4})-(\d{2})-(\d{2})/g,"$2/$3/$1")
"05/20/2020"
"bryent".replace(/(br)/,"_$1_")
"_br_yent"
"bryent".replace(/(?:br)/,"_$1_") // ?:表示只分组不捕获
"_$1_yent"
前瞻
正则表达式从文本头部向尾部开始解析,文本尾部方向,称为“前”;前瞻就是在正则表达式匹配到规则的时候,向前检查是否符合断言
- 正向前瞻:excp(?=assert)
- 负向前瞻(非的意思):excp(?!assert)
'a8*34vv'.replace( /\w(?=\d)/g , 'X') // 表示匹配的是后面跟着的值是数字的 单词字符
"X8*X4vv"
'a8*34vv'.replace( /\w(?!\d)/g , 'X') // 表示匹配的是后面跟着的值不是数字的 单词字符
"aX*3XXX"
对象属性
- global: 是否全文搜索,默认false
- ignoreCase: 是否大小写敏感,默认false
- multiline: 是否多行搜索,默认false
- lastIndex:是当前表达式匹配内容的最后一个字符的下一个位置
- source: 正则表达式的文本字符串
对象方法
- test方法:用于检测字符串是否符合规则,返回一个布尔值。如正则表达式设置了全局匹配,此方法的执行会改变原正则表达式的lastIndex属性,再次执行时会通过lastIndex开始匹配;
// 同一个正则对象全局执行多次可能会得到我们并不想要的结果,这个情况可以去掉全局匹配,或者每次匹配的时候新建一个正则对象 如:/foo/g.test('foo')
var regex = /foo/g;
// regex.lastIndex is at 0
regex.test('foo'); // true
// regex.lastIndex is now at 3
regex.test('foo'); // false
- exec方法:在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。同test方法,在设置了 global 或 sticky 标志位的情况下(如 /foo/g or /foo/y),JavaScript RegExp 对象是有状态的。他们会将上次成功匹配后的位置记录在 lastIndex 属性中。
let reg1= /\bfoot\d\b/g
reg1.exec('foot1 and footer and football,foot2')
// ["foot1", index: 0, input: "foot1 and footer and football,foot2", groups: undefined]
reg1.exec('foot1 and footer and football,foot2')
// ["foot2", index: 30, input: "foot1 and footer and football,foot2", groups: undefined]
let reg2= /\bfoot(\d)\b/g // 包含分组时
reg2.exec('foot1 and footer and football,foot2')
// ["foot1", "1", index: 0, input: "foot1 and footer and football,foot2", groups: undefined]
reg2.exec('foot1 and footer and football,foot2')
// ["foot2", "2", index: 30, input: "foot1 and footer and football,foot2", groups: undefined]
字符串方法
- search 如果匹配成功,则 search() 返回正则表达式在字符串中首次匹配项的索引;否则,返回 -1
var str = "hey JudE";
var re = /[A-Z]/g;
console.log(str.search(re)); // 4
- match 正则表达式不包含 g 标志,str.match() 将返回与 RegExp.exec(). 相同的结果。
var str = 'For more information, see Chapter 3.4.5.1';
var reg = /see (chapter \d+(\.\d)*)/ig;
str.match(reg); // ["see Chapter 3.4.5.1"]
// 不包含g
var re = /see (chapter \d+(\.\d)*)/i;
str.match(re);// ["see Chapter 3.4.5.1", "Chapter 3.4.5.1", ".1", index: 22, input: "For more information, see Chapter 3.4.5.1", groups: undefined]
- replace 第一个参数是正则,第二个参数是目标值。目标值可以是普通字面量,也可以说正则分组值$1,$2。还可以是一个回调,回调有四个参数,分别是 匹配的值,分组值(如有),索引,原字符串
'a1b2c3'.replace(/\d/g,function(match,index,source){
return parseInt(match+1)
})
// a2b3c4
'a1b2c3d4e5'.replace(/(\d)(\w)(\d)/g,function(match,group1,group2,group3,index,source){
return group1+group3
})
// a12c34e5