正则表达式
概述
正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用来按照“给定模式”匹配文本。比如,正则表达式给出一个 Email 地址的模式,然后用它来确定一个字符串是否为 Email 地址。JavaScript 的正则表达式体系是参照 Perl 5 建立的。
新建正则表达式有两种方法。一种是使用字面量,以斜杠表示开始和结束。
1 | var regex = /xyz/; |
另一种是使用RegExp构造函数。
1 | var regex = new RegExp('xyz'); |
上面两种写法是等价的,都新建了一个内容为xyz的正则表达式对象。它们的主要区别是,第一种方法在引擎编译代码时,就会新建正则表达式,第二种方法在运行时新建正则表达式,所以前者的效率较高。而且,前者比较便利和直观,所以实际应用中,基本上都采用字面量定义正则表达式。
RegExp构造函数还可以接受第二个参数,表示修饰符(详细解释见下文)。
1 | var regex = new RegExp('xyz', 'i'); |
上面代码中,正则表达式/xyz/有一个修饰符i。
修饰符
g
修饰符
默认情况下,第一次匹配成功后,正则对象就停止向下匹配了。g
修饰符表示全局匹配(global),加上它以后,正则对象将匹配全部符合条件的结果,主要用于搜索和替换。
i
修饰符
默认情况下,正则对象区分字母的大小写,加上i
修饰符以后表示忽略大小写(ignorecase)。
元字符
元字符 | 描述 |
---|---|
\d |
查找数字 [0-9] |
\D |
非数字字符 [^0-9] |
\w |
单词字符 [a-zA-Z0-9_] |
\W |
非单词字符 [^a-zA-Z0-9_] |
\s |
不可见字符,包含空格 [\f\r\n\t\v] |
\S |
非不可见字符 [\f\r\n\t\v] |
\t |
查找制表符 |
. |
除了换行和回车之外的任一字符 [^\n\r] |
运算符
运算符 | 描述 |
---|---|
() |
提升优先级,优先级最高 ,一个 () 表示一个组匹配 |
[] |
表示一个字符的位置,[] 中定义需要匹配的字符 |
^ |
[] 中表示非 , // 中表示匹配开始位置 |
{} |
定义量词,表示某字符出现的次数 |
|
表示或者,优先级最低。
注:1. 在 []
中,特殊字符不需要使用 \
进行转义处理,但是如果需要使用 []
匹配 \
自身的话,那么就需要转义。
2. 对于字符 -
来说,如果是放在数字或字母之间,则表示匹配这一段范围的字符,否则就是匹配 -
自身。
1 | // 匹配 \ |
量词
格式 | 描述 |
---|---|
x{n,m} |
表示 x 出现 n 至 m 次 , x>=n && x<=m |
x{n,} |
x 出现 n 个以上 ,x>=n |
x{n} |
x 出现 n 个 ,x==n |
x+ |
x 出现 1个 或 1个 以上,x>=1 |
x* |
x 出现 0个 或 0个 以上,x>=0 |
x? |
x 出现 0个 或 1个,x==0 或 x==1 |
^x |
以x开始 |
x$ |
以x结尾 |
转义符
如果需要匹配特殊字符(比如:RegExp 中使用到的特殊字符)。那么,我们需要对这些字符使用 \
进行转义。
需要转义的特殊字符有:
\
/
+
-
*
.
{
}
^
$
(
)
[
]
例如,匹配 /
字符时,我们需要转义。
1 | (/\//.test('/')) |
注意:
如果是以 new RegExp()
构造函数的方式定义正则表达式,由于其中的参数是字符串类型,所以在转义的时候需要使用两个 \\
进行转义。
1 | (new RegExp('\\/').test('/')) |
特殊的:
在对 \
进行匹配时,需要进行特殊处理,原因是 \
本身就是转义符。以下分别是以字面量方式和构造函数定义正则时的写法。
1 | //1. 字面量 |
注:传入的
\\
测试字符加入了 2 个,是因为 javascript 引擎会认为需要将右边的引号'
转义,所以加一个\
。
RegExp实例方法
RegExp.prototype.test()
检索字符串是否满足正则表达式的要求。
参数:string
类型,需要检测的字符串
返回值:boolean
类型 ,true
表示匹配满足正则表达式要求,false
表示不满足要求
RegExp.prototype.exec()
正则实例对象的exec
方法,用来返回匹配结果。如果发现匹配,就返回一个数组,成员是匹配成功的子字符串,否则返回null
。
1 | var s = '_x_x'; |
上面代码中,正则对象r1
匹配成功,返回一个数组,成员是匹配结果;正则对象r2
匹配失败,返回null
。
如果正则表示式包含圆括号(即含有“组匹配”),则返回的数组会包括多个成员。第一个成员是整个匹配成功的结果,后面的成员就是圆括号对应的匹配成功的组。也就是说,第二个成员对应第一个括号,第三个成员对应第二个括号,以此类推。整个数组的length
属性等于组匹配的数量再加1。
1 | var s = '_x_x'; |
上面代码的exec
方法,返回一个数组。第一个成员是整个匹配的结果,第二个成员是圆括号匹配的结果。
exec
方法的返回数组还包含以下两个属性:
input
:整个原字符串。index
:整个模式匹配成功的开始位置(从0开始计数)。
1 | var r = /a(b+)a/; |
上面代码中的index
属性等于1,是因为从原字符串的第二个位置开始匹配成功。
如果正则表达式加上g
修饰符,则可以使用多次exec
方法,下一次搜索的位置从上一次匹配成功结束的位置开始。
1 | var reg = /a/g; |
上面代码连续用了四次exec
方法,前三次都是从上一次匹配结束的位置向后匹配。当第三次匹配结束以后,整个字符串已经到达尾部,匹配结果返回null
,正则实例对象的lastIndex
属性也重置为0
,意味着第四次匹配将从头开始。
利用g
修饰符允许多次匹配的特点,可以用一个循环完成全部匹配。
1 | var reg = /a/g; |
上面代码中,只要exec
方法不返回null,就会一直循环下去,每次输出匹配的位置和匹配的文本。
正则实例对象的lastIndex
属性不仅可读,还可写。设置了g
修饰符的时候,只要手动设置了lastIndex
的值,就会从指定位置开始匹配。
常见验证
邮箱
前面是字母或者数字
必须有@
@后面是字母或者数字
必须有.
.后面是字母或者数字
1 | var r = /^\w+@\w+(\.\w+)+$/; |
手机号
11位数字组成
号段13[0-9] 147 15[0-9] 177[0178] 18[0-9]
1 |
|
中文名
只能是汉字
长度2-6位之间
汉字范围[\u4e00-\u9fa5]
1 | var r = /^[\u4e00-\u9fa5]{2,6}$/; |
小数位数
只能是数字
小数位数不得超过 2 位
1 | var r = /^\d+(.\d{1,2})?$/ |
金额验证
十进制位及以上不能为 0
最多保留2位小数
必需为数值
可以为空
1 | var r = new RegExp("^(((^[1-9]\\d*)|(^[0-9]))+(\\.\\d{1,2})?)?$") |