写在前面
正则真是个伟大的发明啊。分分钟提高工作效率,
以前删除某个文件夹下面的文件(Mac):
command + A && command + delete
现在只需在命令行下
rm -rf *
而且如果你要删除的文件有规律的话,
// 删除开头为'2017-11-'的所有文件
rm -rf 2017-11-*
// 删除.txt文件
rm -rf *.txt
简直是进入现代化啊。总而言之,学好正则非常必要啊。
本文的代码使用JavaScript
书写。javascript 对正则的实现基于RegExp对象。其说明文档在(MDN-RegExp介绍),可以了解下。
一、几个概念
正则表达式
正则表达式是描述一组字符串特征的模式,用来匹配特定的字符串。——Ken Thompson
字符串字面值 原生的字符串,没有添加正则元素在里面,看到什么就是什么。比如Hello world
这个就是一个字面值。
元字符 在正则表达式中有特殊含义的字符,是正则表达式保留字。比如*
、+
、?
、[
、]
字符组 用于匹配字符的集合,通常置于[]
内,如[0-9]
、[a-z]
字符组简写式
如其名字所说,是字符组的简写形式。如\d
匹配数字,相当于[0-9]
,使用简写式可以使表达式更精炼。
捕获分组vs
非捕获分组 正则表达式中通常用括号(分组内容)
来表示一个捕获分组,以便后续对其引用,它通常和 后向引用 相联系。与之相对的是非捕获分组(?:分组内容)
。因为非捕获分组不会存储到内存中,通常性能会好于捕获分组。如:(abc)#\1
可以匹配abc#abc
,这里\1
引用了前面的(abc)
,非捕获分组表示abc 则可以写成(?:abc)
量词 量词用于描述某个模式出现的个数。
* 用于表示0个或多个
?表示0个或1个
+ 表示1个或多个
{n} 表示出现n个
边界 用来标记字符串中的位置,如^
和
$ 分别用于匹配行的起始和结束位置。\b
用于标记单词的边界.
二、简单的模式匹配
2.1 匹配字符串字面量
var hw = /hello world/;
hw.test('hello world');// true
2.2 匹配数字和非数字
对于单个数字,我们可以用[0-9]
,也可以用\d
,当然也可以用[0123456789]
,根据具体需要我们也可以选择部分数字进行匹配[12]
,这只会匹配1和2。
// 匹配0-9的数字
var reg1 = /[0-9]/;
// 简写形式
var reg2 = /\d/;
reg1.test('5');
reg2.test('5');
举个例子,我们可以用数字匹配来验证年份。
// 匹配1000 ~ 2999
var yearReg = /^[1-2]\d\d\d$/;
yearReg.test('1970');
yearReg.test('2999');
与\d
相反的是\D
用于匹配非数字字符,它相当于[^\d]
2.3 匹配单词和非单词字符
\w
用于匹配单词字符,何谓单词字符,其实就相当于[_a-zA-Z0-9]
,既数字、字母、和下划线。
同样它的相反是\W
,大写的W
2.4 匹配空白符
\s
用于匹配空白符,它相当于[ \t\n\r]
,既空格、制表符(\t
)、换行符(\n
)、回车符(\r
)。
这个应用就挺大了,比如利用replace()可以把文本中的空白符去掉。
var sReg = /\s/;
var text = 'wor ld';
// 删除空白字符
text.replace(sReg, '');//world
2.5 匹配任意字符
.
用于匹配任意字符。结合量词我们可以用来匹配字符长度。
var reg = /^.{4}$/;
reg.test('-R3s');
reg.test('hello');
三、选择、分组和引用
3.1 选择
选择操作可以在多个子模式中选择一种,(html|HTML)
可以匹配html也可以匹配HTML,
var reg = /<(html|HTML)>/;
reg.test('<html>');//true
reg.test('<HTML>');//true
3.2 捕获分组和后向引用
前面提到过,()
表示一个捕获分组,括号代表一个分组的开始,从左到右分别1、2、3……,引用的时候就可以用\1
、\2
来引用了。
// 这里\1表示前面的(html|HTML)
var reg = /<(html|HTML)>.*<\/\1>/;
reg.test('<html><body></body></html>');//true
reg.test('<HTML><body></body></HTML>');//true
3.3 非捕获分组
有时候我们的分组并不需要后面引用,这时候可以使用非捕获分组来提升性能。
// 判断广东省广州市的电话号码
var reg = /^(?:020)-\d{8}$/;
reg.test('020-88886666');//true
// 判断151或127开头的手机号
var reg2 = /^(?:151|127)\d{8}$/;
reg2.test('15166668888');//true
四、匹配Unicode字符
\uXXXX
或者\xxx
用于匹配Unicode 字符,
"京"的Unicode编码为\u4eac
那么我们可以尝试匹配一下北京的车牌号:
var reg = /^\u4eac[A-Z][0-9_A-Z]{5}$/;
reg.test('京AF2345');//true
五、结语
正则表达式是相当强大的工具,这篇文章只能算是自己入门的一个简单的总结。还有许多特性等待在实践中发掘。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。