1. JS 正则概念: 用来处理字符串的规则。
每一个正则表达式都是由元字符和修饰符组成。
元字符: 在 / / 之间具有意义的一些字符
修饰符:g(全局匹配) 、i(忽略大小写)、m(多行匹配)
\
转义字符
^
以某元字符开始 /^\d/
以数字开头
$
以某元字符结束 /\d$/
以数字结束
.
除了 \n
以外的任意字符
代表出现次数的量词元字符:
*
出现零到多次
+
出现一到多次
?
普通元字符后表示出现零到一次;量词元字符后表示取消捕获的贪婪性;
{n}
出现n次
{n,}
出现n到多次
{n,m}
出现n到m次
x|y
x或者y中的一个
[xyz]
x或者y或者z中的一个
[^xyz]
除了xyz以外的任意一个字符
[a-z]
a-z中的任何一个字符 (中括号内不识别两位数;中括号中的字符均表示本身,没有特殊含义 )
[^a-z]
除了a-z中的任意一个字符
\d
一个0-9之间的数字
\D
一个除了0-9以外的任意字符
\b
匹配一个边界符
\s
匹配一个空白字符
\w
数字、字母、下划线中的任意一个字符 等价于 [0-9a-zA-Z_]
()
分组 var reg = /^(\d+)test(\d+)$/
作用:
1. 小括号()改变默认的优先级;
var reg = /^18|19$/;
//18,19,1819,189,119,819…均为true
var reg = /^(18|19)$/;
//18 或 19
2. 分组引用
\1
代表和第一个分组出现相同的内容;\2
代表和第二个分组出现相同的内容
var reg = /^(\w)\1(\w)\2$/;
// 匹配 aabb型
reg.test('aabb');
// true
reg.test('ccds');
// false
3. 分组捕获:正则在捕获时,不仅仅把大正则匹配的内容捕获到,而且还可以把小分组匹配的内容捕获到。
var reg = /^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/; //检测身份证
var str = '142726199009181211';
reg.exec(str);
// ["142726199009181211", "14", "2726", "1990", "09", "18", "12", "1", "1", index: 0, input: "142726199009181211"]
//若不想捕获某小分组的内容,只需在分组内容前加 ?:
var reg = /^(?:\d{2})(?:\d{4})(?:\d{4})(?:\d{2})(\d{2})(\d{2})(\d)(\d|X)$/; //检测身份证
var str = '142726199009181211';
reg.exec(str);
// ["142726199009181211", "18", "12", "1", "1", index: 0, input: "142726199009181211"]
2. 创建正则
- 字面量方式:
var reg = /\d+/;
注:在字面量创建方式中,/ /之间包含的内容都是元字符,不能提供字符串拼接的方式把变量添加进正则表达式。
例如:
var name = 'VisonYH';
var reg = /^\d+"+name+"\d+$/; //错误,变量name不会被添加进正则表达式
- 实例创建方式:
var reg = new RegExp("\\d+",'g'); //需要转义,修饰符作为第二个参数添加
注:可以进行字符串拼接。
例如:
var name = 'VisonYH';
var reg = new RegExp("^\\d+" + name + "\\d+$", 'g'); //匹配2018VisonYH2018
3. 正则中的方法
- test 方法(匹配):判断当前字符串是否符合当前规则;
var reg = /\d/;
console.log(reg.test('我是一段字符串')); //false
console.log(reg.test('你好,2018')); //true
- exec 方法(捕获): 把字符串中符合规则的内容捕获到数组中并返回;
捕获的数组内容组成:[‘匹配字符串’,’匹配字符串的起始索引’,’匹配的原始字符串’ ]
var reg = /\d/;
console.log(reg.exec('我是一段字符串')); //null
console.log(reg.exec('你好,2018')); //["2", index: 3, input: "你好,2018"]
- 字符串的match 方法(把所有和正则匹配的字符都获取到)
var reg = /\d+/;
var str = '2018VisonYH2018';
str.match(reg); // ["2018", index: 0, input: "2018VisonYH2018"]
var reg = /\d+/g;
var str = '2018VisonYH2018';
str.match(reg); // ["2018", "2018"]
var reg = /\d+?/g;
var str = '2018VisonYH2018';
str.match(reg); // ["2", "0", "1", "8", "2", "0", "1", "8"]
注:在正则表达式中有分组的情况下,match
方法失效。
- replace方法
字符串的replace方法只能替换第一个匹配到的字符串;
var str = '2017VisonYH2017';
str.replace('2017','2018'); // "2018VisonYH2017"
将待替换的字符串换成正则表达式之后:
var str = '2017VisonYH2017';
str.replace(/2017/g,'2018'); // "2018VisonYH2018"
原理:
将replace方法的第二个参数换成一个匿名函数,例如:
var str = '2017VisonYH2017';
str.replace(/2017/g,function(){
console.log(arguments);
return '2018';
});
执行结果如图:
由此可知:
(1)匿名函数执行多少次取决于正则捕获多少次;
(2)匿名函数的参数就是正则表达式执行的exec()
方法的结果;
(3)匿名函数的返回值将字符串中捕获到的内容替换。
4. 正则的特性
- 正则捕获具有懒惰性
其属性lastIndex
的值为0,意味着每次从索引值为0处开始查找;在正则表达式后加g,如/\d+/g
则可将lastIndex
值记录为该次捕获到的位置,因而可以消除懒惰性,接下来的捕获从lastIndex
记录的位置开始。
例子:
var reg = /\d+/g;
reg.exec('2018VisonYH2018'); // ["2018", index: 0, input: "2018VisonYH2018"]
reg.exec('2018VisonYH2018'); // ["2018", index: 11, input: "2018VisonYH2018"]
reg.exec('2018VisonYH2018'); // null
- 正则捕获具有贪婪性
正则的每一次捕获都是按照最长的结果捕获的,例如:2符合正则,2018也符合正则,则默认捕获的是2018.
解决正则的贪婪性只需在量词元字符后加?
即可,例如:
var reg = /\d+?/;
reg.exec('2018VisonYH'); // ["2", index: 0, input: "2018VisonYH"]
5. 案例
- 判断有效数字的正则
// 正数、负数、小数、0
// '.'可以出现也可以不出现
// 多位数第一位数字可以为0,一位数不能以0开头
var reg = /^[+-]?(\d|([1-9]\d+))(\.\d+)?$/
- 年龄为18-65之间的数字
var reg = /^(1[89]|[2-5]\d|6[0-5])$/;
- 将字符串中的数字替换成大写的汉字
var str = '20180123';
var arr = ['零','壹','贰','叁','肆','伍','陆','柒','捌','玖'];
var reg = /\d/g;
str.replace(reg, function() {
return arr[arguments[0]];
});
执行结果如图:
- 模板引擎简单原理
var str = 'My name is {0}, I am {1} years old, I am from {2}';
var data = ['VisonYH', 22, 'China'];
str.replace(/{(\d+)}/g, function() {
return data[arguments[1]];
});
执行结果为:
- URL 解析
var str = 'https://www.baidu.com/link?url=zuYrA3Z5MNU572dRzJVtr2lY6kkE6mWhKhe3PKtRoTy&wd=&eqid=910fa42d00010142000000055a66f992';
var reg = /([^&?=]+)=([^&?=]+)/g;
var obj = {};
url.replace(reg, function() {
obj[arguments[1]] = arguments[2];
return arguments[0];
});
执行结果为:
参考文献:
1. 阮一峰:RegExp对象