1 为什么要用正则表达式?
学习之前,多想想为什么要使用正则表达式,有助于理解。
正则表达式
regular expression
使用单个字符串来描述某个句法规则,计算机根据规则去匹配字符串中的内容。
正则表达式的性能高于常规字符串操作(省略循环、遍历等操作)
正则表达式仅用于字符串的操作
2 常规字符串操作与正则表达式的比较
要提取出字符串中'ashx521dasbx34sasdz275dasdzxd897'
中连续的数字,并将结果保存在数组中['521', '34', '275', '897']
-
传统字符串操作:需要遍历整个字符串,判断每个字符是否在
'0'-'9'
之间再进行相应的操作/** * 使用一个暂时变量tmp保存连续为数值时的字符串,间断后再统一加入数组内; * 可能会出现最后一位是数字的情况,所以使用i<=str.length多走一次循环的else路径,将最后一组数组加入数组 * */ function findNum_two(str) { var arr = []; var tmp = ''; // 遍历字符串,取出需要的数字 for(var i=0; i<=str.length; i++) { if(str.charAt(i) <= '9' && str.charAt(i) >= '0') { tmp += str[i]; } else { if(tmp) { // 如果tmp不为空 arr.push(tmp); tmp = ''; } } } return arr; } console.log(findNum_two(str)); // [ '521', '34', '275', '897' ]
-
使用正则表达式:只需使用字符串的
match()
方法去匹配指定的规则(正则表达式即可)function findNum (str) { return str.match(/\d+/g); } console.log(findNum(str)); // [ '521', '34', '275', '897' ]
3 正则表达式写法
字面量写法:
var re = /\d+/gi;
构造函数写法:
var re = new RegExp('\\d+', 'gi');
注意两个\\
,因为JavaScript中\
需要转义
3.1 正则表达式中的转义字符
转义字符:单独使用字母本身有意义;在前面加上
\
后改变原有意义
3.2 量词
用来描述相邻的前面的单个字符匹配规则出现的次数
量词使用
{a, b}
表示,其中b
可以省略,意义不同
3.3 字符类
使用
[]
描述一类字符,整体只代表一个字符,表示该字符在某个范围内。/a[0-9]c/
匹配三位字符串,第一位是a
,第三位是c
,第二位是'0'-'9'
之间的任何一位都可以匹配成功[]
多种规则是或 |
的关系:[0-9a-zA-Z]
等
整个字符类
[0-9a-zA-Z]
只代表一位字符
注意,字符类中的^
表示非的意思,不在某个范围内:[^\d]
表示非数字的字符
3.4 修饰符
g
--global
:全局匹配,找到所有的匹配项,不是在第一个匹配后停止i
--ignored
:忽略大小写m
:多行,将开始字符^
和结束字符$
视为在多行上工作(每匹配一行的开始和结束以\n
和\r
分割)u
:将模式视为Unicode序列点的序列
3.5 匹配子项
对于复杂的正则表达式,可以使用
()
将其拆分为多个部分,在replace(re, fn)
回调函数中可以简化匹配内容的操作
var re = /(\d+)(\w)(\S)/;
fn($0, $1, $2 ...)
$0
代表正则表达式本身匹配到的内容:(\d+)(\w)(\S)
$1
代表正则表达式的第一个匹配子项:(\d+)
$2
代表正则表达式第二个匹配子项:(\w)
...
3.6 重复子项
主要用于匹配字符串中重复的字符
var re = /(a)(b)(c)\1/;
:\1
表示重复的第一个子项(b)
,第4个位置的字符与第1个位置的字符相同var re = /(a)(b)(c)\2/;
:\2
表示重复的第二个子项(b)
,第4个位置的字符与第2个位置的字符相同var re = /(a)(b)(c)\3/;
:\3
表示重复的第三个子项(c)
,第4个位置的字符与第3个位置的字符相同...
3.7 逻辑或|
使用
|
代表逻辑或,|
左右两个操作数只要有一个满足要求即可
3.8 开始、结束标记
不在
[]
中使用^
,^
表示以最近的匹配字符规则开始整个匹配;$
表示以最近的匹配规则结束匹配
作用范围只是^
之后的第一个子项;$
前的第一个子项
4 正则表达式的方法
主要有4中方法用于操作正则表达式:
match()
、replace()
、search()
是字符串的操作方法test()
、exec()
是正则表达式对象的操作方法
4.1 test()
根据
RegExp
去匹配字符串,如果匹配成功,返回true
;匹配失败返回false
。主要用于逻辑判断
var str = "abxe2312dafxz";
var re = /\d+/;
re.test(str); // true
4.2 search()
根据
RegExp
去匹配字符串,返回第一个匹配成功字符串的首字符的索引;匹配失败返回-1
。用于查找字符的索引,类似字符串的indexOf()
方法
str.search(re)
4.3 match()
根据
RegExp
去匹配字符串,如果匹配成功,将匹配的结果保存在数组中返回;匹配失败返回null
。默认第一次匹配后便停止继续匹配,使用修饰符g
进行全局匹配
str.match(re)
4.4 replace(re, newstr)
方法
根据
RegExp
去匹配字符串,如果匹配成功,将匹配的字符串更换为新的字符串newstr
。
replace()
方法的参数re
正则表达式是变量,必须使用new RegExp()
方式创建re
var str = 'a23gb';
var re = /\d+/;
str.replace(re, "xy"); // 'axygb'
replace()
方法的第二个参数可以是回调函数,其参数是每次匹配成功获取的字符串。每次匹配成功都会执行一次回调函数
5 实践
5.1 找到一个字符串中出现次数最多的字符及其出现的次数
var str = '1231asdaegj71836178asdhasssasalsdhdzxbczaslazxcnnffajshdhgagsgdssssasdzzxda';
var str = str.split('').sort().join(''); // 按顺序的字符序列
var re = /(\w)\1+/g;
var length = 0;
var val = ''; // 保存出现次数最多的字符
// $0代表每次匹配到的字符,$1代表第一个正则表达式子项(\w)
str.replace(re, function ($0, $1) { // 可以将匹配的字符当做变量操作
if($0.length > length) {
length = $0.length;
val = $1; // $1代表每次匹配的字符
}
});
console.log(length);
console.log(val);
5.2 去掉字符串前后的空格
var re = /^\s+|\s+$/g;
,使用字符串应用正则即可:str.replace(re, '')
5.3 常用正则匹配规则
QQ号:
var re = /^[1-9]\d{4,11}$/;
:第一位是1-9中的数字,最后也是数字,总共5-12位中文匹配:
var re = /[\u4e00-\u9fa5]/;
:使用Unicode编码进行匹配email
:var re = /\w+@[a-z0-9]+(\.[a-z]+){1,3}/;
:可能出现.com.cn.net
身份证:
var re = /[1-9]\d{14}|[1-9]\d{17}|[1-9]\d{16}x/i;
邮编:
var re = /[1-9]\d{5}/;
5.3 将常用正则表达式封装在一个对象中便于使用
var re = {
email: /\w+@[a-z0-9]+(\.[a-z]+){1,3}/,
chinese: /[\u4e00-\u9fa5]/,
qq: /^[1-9]\d{4,11}$/,
id: /[1-9]\d{14}|[1-9]\d{17}|[1-9]\d{16}x/i,
trim: /^\s+|\s+$/
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。