JavaScript学习总结(八)正则表达式

基本概念

正则表达式是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”)。模式描述在搜索文本时要匹配的一个或多个字符串。

首先推荐几个正则表达式编辑器

Debuggex :https://www.debuggex.com/

Regexper:http://www.regexper.com/

JavaScript RegExp 对象参考手册:http://w3school.com.cn/jsref/jsref_obj_regexp.asp

正则表达式是一种查找以及字符串替换操作。正则表达式在文本编辑器中广泛使用,比如正则表达式被用于:

1
2
3
4
检查文本中是否含有指定的特征词
找出文中匹配特征词的位置
从文本中提取信息,比如:字符串的子串
修改文本

说明:正则表达式通常用于两种任务:1.验证,2.搜索/替换。用于验证时,通常需要在前后分别加上^和$,以匹配整个待验证字符串;搜索/替换时是否加上此限定则根据搜索的要求而定,此外,也有可能要在前后加上\b而不是^和$。此表所列的常用正则表达式,除个别外均未在前后加上任何限定,请根据需要,自行处理。

优先权顺序

在构造正则表达式之后,就可以象数学表达式一样来求值,也就是说,可以从左至右并按照一个优先权顺序来求值。 下表从最高优先级到最低优先级列出各种正则表达式操作符的优先权顺序:

操作符 描述
\ 转义符
(), (?:), (?=), [] 圆括号和方括号
*, +, ?, {n}, {n,}, {n,m} 限定符
^, $, \anymetacharacter 位置和顺序

字符类匹配

字符 描述
[…] 查找方括号之间的任何字符。
[^…] 查找任何不在方括号之间的字符。
. 查找单个字符,除了换行和行结束符。
\w 查找单词字符。
\W 查找非单词字符。
\d 查找数字。
\D 查找非数字字符。
\s 查找空白字符。
\S 查找非空白字符。
\b 匹配单词边界。
\B 匹配非单词边界。

重复字符匹配

字 符 匹配
{n,m} 匹配前一项至少n次,但不能超过m次
{n,} 匹配前一项n次或更多次
{n} 匹配前一项n次
? 匹配前一项0次或者1次,也就是说前一项是可选的,等价于{0,1}
+ 匹配前一项1次或多次,等价于{1,}
* 匹配前一项0次或多次,等价于{0,}

字符类:锚字符 匹配

元字符/元符号 匹配
$ 匹配字符串的结尾,在多行检索中,匹配一行的结尾
^ 匹配字符串的开头,在多行检索中,匹配一行的开头
\A 只有匹配字符串开始处
\b 匹配单词边界,词在 []内时无效
\B 匹配非单词边界
\G 匹配当前搜索的开始位置
\Z 匹配字符串结束处或行尾
\z 只匹配字符串结束处

字符类:记录字符 匹配

元字符/元符号 匹配情况
(string) 用于反向引用的分组
\1 或$1 匹配第一个分组中的内容
\2 或$2 匹配第二个分组中的内容
\3 或$3 匹配第三个分组中的内容

量词

量词 描述
n+ 匹配任何包含至少一个 n 的字符串。
n* 匹配任何包含零个或多个 n 的字符串。
n? 匹配任何包含零个或一个 n 的字符串。
n{X} 匹配包含 X 个 n 的序列的字符串。
n{X,Y} 匹配包含 X 至 Y 个 n 的序列的字符串。
n{X,} 匹配包含至少 X 个 n 的序列的字符串。
n$ 匹配任何结尾为 n 的字符串。
^n 匹配任何开头为 n 的字符串。
?=n 匹配任何其后紧接指定字符串 n 的字符串。
?!n 匹配任何其后没有紧接指定字符串 n 的字符串。

正则表达式修饰符

字符 含义
i 执行不区分大小写的匹配
g 执行一个全局匹配,即找到所有匹配而非一次匹配
m 多行匹配模式,^匹配一行的开头和字符串开头,$匹配行的结束和字符串的结尾

RegExp的方法

RegExp 对象有 3 个方法:test()、exec()以及 compile()

方法 描述
test() 检索字符串中指定的值。返回 true 或 false。
exec() 检索字符串中指定的值。返回找到的值,并确定其位置。
compile() 编译正则表达式。既可以改变检索模式,也可以添加或删除第二个参数。

String 对象中的正则表达式方法

方法 描述
search() 检索与正则表达式相匹配的值。
match() 找到一个或多个正则表达式的匹配。
replace() 替换与正则表达式匹配的子串。
split() 把字符串分割为字符串数组。

match 方法

1
2
3
4
5
/*使用 match 方法获取获取匹配数组*/ 
var pattern = /box/ig;//全局搜索
var str = 'This is a Box!,That is a Box too';
alert(str.match(pattern)); //匹配到两个 Box,Box
console.log(str.match(pattern).length);//获取数组的长度

search方法

1
2
3
4
/*使用 search 来查找匹配数据*/
var pattern = /box/ig;
var str = 'This is a Box!,That is a Box too';
console.log(str.search(pattern));//10 查找到返回位置,否则返回 -1

replace方法

1
2
3
4
/*使用 replace 替换匹配到的数据*/
var pattern = /box/ig;
var str = 'This is a Box!,That is a Box too';
console.log(str.replace(pattern, 'Cat'));//This is a Cat!,That is a Cat too

split方法

1
2
3
4
5
/*使用 split 拆分成字符串数组*/

var pattern = / /ig;
var str = 'This is a Box!,That is a Box too';
console.log(str.split(pattern));//将空格拆开分组成数组

exec方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 统计子字符串出现的所有位置*/

function count(str){
var b,r=/def/g;
while(b = r.exec(str)){
console.log(b);
}
}
count('abcdefabcdefabcdefabcdef');

输出:
[ 'def', index: 3, input: 'abcdefabcdefabcdefabcdef' ]
[ 'def', index: 9, input: 'abcdefabcdefabcdefabcdef' ]
[ 'def', index: 15, input: 'abcdefabcdefabcdefabcdef' ]
[ 'def', index: 21, input: 'abcdefabcdefabcdefabcdef' ]

建立正则表达式

直接量语法

1
/表达式/修饰符

创建 RegExp 对象的语法:

1
new RegExp(字符串, 可选修饰符);

例子:

1
2
3
4
//用户名正则,4到16位(字母,数字,下划线,减号)
var uPattern = /^[a-zA-Z0-9_-]{4,16}$/;
//输出 true
console.log(uPattern.test("iFat3"));

正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

正则表达式选择

一个正则表达式选择包含1个或多个正则表达式序列。这些序列被竖线(|)字符分隔。如果这些序列中的任何一项符合匹配条件,那么这个选择就被匹配。他会按顺序依次匹配

1
"into".match(/in | int/);

以上将在into中匹配in。但他不会匹配int,因为in已经匹配成功了。

正则表达式转义

1
\ / [ ] () { }  ? + * | . ^ $

如果希望按字面去匹配上面的字符,那么必须用一个\前缀来进行转义。\前缀不能使字母或数字字面化。

1
2
3
4
5
6
7
8
9
10
\f : 换页符
\n : 换行符
\r : 回车符
\t : 制表(tab)符

\^ 匹配 ^ 符号本身

\$ 匹配 $ 符号本身

\. 匹配小数点(.)本身

实例

1
2
3
String.prototype.trim = function () {
return this.replace(/(^\s*)|(\s*$)/g,'');
};

^表示字符串必须以后面的规则开头,而(^\s*) 表示的就是以0个空格或者多个空格开头,后面的(\s*$)的意思就是, 以0个空格或者多个空格结尾。

匹配特定字符串

1
2
3
4
5
^[A-Za-z]+$  //匹配由26个英文字母组成的字符串
^[A-Z]+$  //匹配由26个英文字母的大写组成的字符串
^[a-z]+$  //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$  //匹配由数字和26个英文字母组成的字符串
^\w+$  //匹配由数字、26个英文字母或者下划线组成的字符串

思维导图:

image

附:常用正则表达式

用户名正则

1
2
3
4
//用户名正则,4到16位(字母,数字,下划线,减号)
var uPattern = /^[a-zA-Z0-9_-]{4,16}$/;
//输出 true
console.log(uPattern.test("iFat3"));

密码强度正则

1
2
3
4
//密码强度正则,最少6位,包括至少1个大写字母,1个小写字母,1个数字,1个特殊字符
var pPattern = /^.*(?=.{6,})(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$/;
//输出 true
console.log("=="+pPattern.test("iFat3#"));

整数正则

1
2
3
4
5
6
7
8
9
10
11
12
//正整数正则
var posPattern = /^\d+$/;
//负整数正则
var negPattern = /^-\d+$/;
//整数正则
var intPattern = /^-?\d+$/;
//输出 true
console.log(posPattern.test("42"));
//输出 true
console.log(negPattern.test("-42"));
//输出 true
console.log(intPattern.test("-42"));

数字正则

可以是整数也可以是浮点数

1
2
3
4
5
6
7
8
9
//正数正则
var posPattern = /^\d*\.?\d+$/;
//负数正则
var negPattern = /^-\d*\.?\d+$/;
//数字正则
var numPattern = /^-?\d*\.?\d+$/;
console.log(posPattern.test("42.2"));
console.log(negPattern.test("-42.2"));
console.log(numPattern.test("-42.2"));

Email正则

1
2
3
4
5
6
7
//Email正则
var ePattern =/^\w+@[a-z0-9]+.[a-z]{2,4}$/

//var ePattern = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;

//输出 true
console.log(ePattern.test("65974040@qq.com"));

手机号正则

1
2
3
4
//手机号正则
var mPattern = /^[1][3][0-9]{9}$/;
//输出 true
console.log(mPattern.test("13900000000"));

身份证号正则

1
2
3
4
//身份证号(18位)正则
var cP = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
//输出 true
console.log(cP.test("11010519880605371X"));

URL正则

1
2
3
4
//URL正则
var urlP= /^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/;
//输出 true
console.log(urlP.test("http://42du.cn"));

日期正则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//日期正则,简单判定,未做月份及日期的判定
var dP1 = /^\d{4}(\-)\d{1,2}\1\d{1,2}$/;
//输出 true
console.log(dP1.test("2017-05-11"));
//输出 true
console.log(dP1.test("2017-15-11"));
//日期正则,复杂判定
var dP2 = /^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/;
//输出 true
console.log(dP2.test("2017-02-11"));
//输出 false
console.log(dP2.test("2017-15-11"));
//输出 false
console.log(dP2.test("2017-02-29"));

IPv4地址正则

1
2
3
4
//ipv4地址正则
var ipP = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
//输出 true
console.log(ipP.test("115.28.47.26"));

包含中文正则

1
2
3
4
//包含中文正则
var cnPattern = /[\u4E00-\u9FA5]/;
//输出 true
console.log(cnPattern.test("42度"));
------ 本文结束 ------
0%