目录
创建方式
- 字面量
var pattern = /js/;
- 构造函数
var pattern = new RegExp('js');
(两种方法得到的都是 RegExp 对象的实例)
匹配方法
- test
语法:正则表达式.test(字符串)
返回值:true/false(找到则返回 true) - exec
语法:正则表达式.exec(字符串)
返回值:数组/null
-
exec 返回值的属性
- index:匹配到的值的起始位置
- input:被匹配的字符串
模式修饰符
- i
不区分大小写(ignoreCase) - g
全局匹配(global) - m
多行匹配(multiline)
简单的转义字符
- \
转义字符(它本身也需要转义) - \n 或 \x0A 或 \u000A
换行 - \t 或 \u0009
Tab键 - \xnn
可根据 ASCII 查询十六进制数 nn(ASCII码对照表) - \uxxxx
可根据 Unicode 查询十六进制数 xxxx(多用于匹配汉字)
字符类
- [ ] 匹配其中的任一字符
-
如:
-
[javascript]
从前往后依次匹配,匹配到任一字符就算匹配完整个正则表达式
- [^] 取反
-
如:
-
[\^js]
匹配除 js 外的任一字符
- [-] 范围
-
如:
-
[a-z]
匹配从 a 到 z 的任一字符 -
[c-e]
-
[c-c]
-
[a-zA-Z]
-
[0-9]
-
[a-z0-9]
-
[a-z0-9@_]
以下会报错:
-
[d-a]
第一个要小于第二个 -
[a-Z]
小写和大写要分开
- 常用字符类
- .
匹配除 \n 外的所有字符,相当于 [^\n] - \w
相当于 [a-zA-Z0-9_] - \W
相当于 [^a-zA-Z0-9_] - \d
相当于 [0-9] - \D
相当于 [^0-9] - \s
匹配空格、制表符 Tab 以及 Unicode 的空白字符 - \S
匹配除了空格、制表符 Tab 以及 Unicode 的空白字符的所有字符 - \u4e00-\u9fa5
中文
- .
重复(量词)
- { } 匹配指定个数
-
如:
-
/\d{3}/
匹配3个 \d -
/\d{2,5}/
匹配2~5个 \d -
/\d{1,}/
匹配1个以上 \d
以下会报错:
-
/\d{2, 5}/
不能加空格 -
/\d{,3}/
第一个数不能省略
- ? 匹配0个或1个
-
如:
-
/\d?/
相当于 /\d{0,1}/
- + 匹配1个以上
-
如:
-
/\d+/
相当于 /\d{1,}/
- * 匹配0个以上
-
如:
-
/\d*/
相当于 /\d{0,}/
非贪婪的重复
- 在量词后加 ?,表示转换为非贪婪匹配
-
如:
-
/a+?/
匹配尽可能少的 a
选择
- | 或者
-
如:
-
/html|css|js/
匹配 html 或 css 或 js
(匹配结果为从左到右最先匹配到的字符串)
分组和引用
- () 分组,捕获
-
如:
-
/(ab)+/
exec 方法返回的数组元素可能为 ababab 和 ab -
/(ab)c/
exec 方法返回的数组元素为 abc 和 ab -
/(a(b(c)))/
exec 方法返回的数组元素为 abc、abc、bc、c
- (?: ) 非捕获
-
如:
-
/(?:ab)c/
exec 方法仅返回 abc
- \1 或 \2 或 …… 表示捕获到的第n个分组
-
如:
-
/(ab)cd\1/
匹配 abcdab
位置匹配(不匹配字符,仅匹配位置)
首尾匹配
- ^ 首匹配
- $ 尾匹配
单词边界匹配
- \b 单词边界
单词前瞻性匹配和负向前瞻性匹配
- 字符串(?=内容) 前瞻性匹配
仅当字符串的后面与内容 一致 时,才匹配
// 匹配后面为 'script' 的 'java'
var str = 'javascript';
var pattern = /java(?=script)/;
console.log(pattern.test(str)); // true
- 字符串(?!内容) 负向前瞻性匹配
仅当字符串的后面与内容 不一致 时,才匹配
// 匹配后面不为 'script' 的 'java'
var str = 'javascript';
var pattern = /java(?!script)/;
console.log(pattern.test(str)); // false
RegExp 对象的实例属性和构造函数属性
实例属性
- lastIndex 从此处开始匹配
默认为 0,全局匹配时会变化为上一次匹配字符串结束位置的后一个位置,有一次匹配不到后重置为 0
// 不加 g 时
var str = 'js js js';
var pattern = /js/;
console.log(pattern.lastIndex); // 0
console.log(pattern.exec(str)); // index 为 0
console.log(pattern.lastIndex); // 0
console.log(pattern.exec(str)); // index 为 0
// 加上 g 时
var str = 'js js js';
var pattern = /js/g;
console.log(pattern.lastIndex); // 0
console.log(pattern.exec(str)); // index 为 0
console.log(pattern.lastIndex); // 2
console.log(pattern.exec(str)); // index 为 3
console.log(pattern.lastIndex); // 5
console.log(pattern.exec(str)); // index 为 6
console.log(pattern.lastIndex); // 8
console.log(pattern.exec(str)); // null
console.log(pattern.lastIndex); // 0
console.log(pattern.exec(str)); // index 为 0
- ignoreCase 判断是否有模式修饰符 i
返回值:true/false - global 判断是否有模式修饰符 g
返回值:true/false - multiline 判断是否有模式修饰符 m
返回值:true/false - source 返回字面量形式的字符串
构造函数属性
- input 或 $_
上一次被匹配的字符串 - lastMatch 或 $&
上一次匹配到的字符 - leftContext 或 $`
上一次匹配位置左边的所有字符 - rightContext 或 $'
上一次匹配位置右边的所有字符 - lastParen 或 $+
上一次匹配到的捕获内容 - $1、$2、……、$99
上一次捕获的第1/2/……/99个字符串(相对常用)
-
如:
-
RegExp.$1
String 对象中与正则相关的方法
其中,参数可传入字符串的方法,将会以构造函数的形式创建相应的正则表达式。
- search(正则或字符串)
返回值:匹配到的字符串的第一个字符所在位置,若未匹配到则返回 -1
注意:不受全局匹配的影响 - match(正则)
返回值:数组/null
返回值的属性:index、input
-
g 全局匹配时
- 将一次性返回所有匹配的字符串。但捕获的内容将不再返回
var str = 'js js js';
var pattern = /js/g;
console.log(str.match(pattern)); // ['js', 'js', 'js']
- split(正则或字符串)
返回值:数组
// 参数为字符串
var str = 'html,css,js';
console.log(str.split(',')); // ['html', 'css', 'js']
// 参数为正则
var str = 'html,css,js';
console.log(str.split(/,/)); // ['html', 'css', 'js']
带有捕获组的模式,各浏览器匹配的行为有些不同
// Chrome
var str = 'abcd';
var pattern1 = /b/;
var pattern2 = /(b)/;
console.log(str.split(pattern1)); // ['a', 'cd']
console.log(str.split(pattern2)); // ['a', 'b', 'cd']
- replace(正则或字符串, 替换成的文本或函数)
返回值:字符串
// 第一个参数为字符串
var str = 'js js js';
console.log(str.replace('js', 'html')); // 'html js js'
// 第一个参数为正则(结合全局匹配 g)
var str = 'js js js';
var pattern = /js/g;
console.log(str.replace(pattern, 'html')); // 'html html html'
// 第一个参数为正则,第二个参数进行引用
var str = 'js js js';
var pattern = /(js)/;
console.log(str.replace(pattern, '<span style="color: red;">$1</span>'));
// '<span style="color: red;">js</span> js js'
// 第一个参数为正则,第二个参数为函数
var str = 'javascript html';
var pattern = /java(script)/;
var newStr = str.replace(pattern, ($0, $1, index, input) => {
console.log($0, $1, index, input); // 'javascript' 'script' 0 'javascript html'
return 'js';
});
console.log(newStr); // 'js html'
其他
全局匹配的注意点
- 全局匹配 g 仅对 test、exec、match、replace 产生影响
- 全局模式只影响 lastIndex(下次搜索的起始位置)
// 中途改变字符串
var pattern = /js/g;
console.log(pattern.lastIndex); // 0
console.log(pattern.exec('js js js')); // index 为 0
console.log(pattern.lastIndex); // 2
console.log(pattern.exec('js js js test test')); // index 为 3
console.log(pattern.lastIndex); // 5
console.log(pattern.exec('js js js')); // index 为 6
console.log(pattern.lastIndex); // 8
console.log(pattern.exec('js js js')); // null
console.log(pattern.lastIndex); // 0
console.log(pattern.exec('js js js')); // index 为 0
match 和 exec 的对比
- match
非全局的情况下才会返回分组中匹配到的内容,全局匹配的时候是把所有匹配到的字符一次性全部返回。 - exec
无论是否全局匹配都会返回分组中匹配到的内容,都只会返回当前匹配到的一个内容,而不是全部返回。
捕获到的内容的使用场景
- exec 返回的数组中
- /(js)\1/ 模式中
- replace 的第二个参数中,$1
- RegExp.$1