JavaScript入门教程

JavaScript简介
JavaScript语法基础
JavaScript流程控制
JavaScript函数
面向对象编程
JavaScript事件
JavaScript DOM
正则表达式
JavaScript BOM
AJAX

专题分析

浏览器兼容性
JS优化
Web前端开发规范
编辑器推荐
总结和笔记

学习助手

对象参考手册
ECMAScript分析
数据中心
QQ交流群

正则表达式范围及重复

我们经常会遇到要描述一个范围的例子,比如,从 0 到 3 的数字,所有的英文字母,包含数字,英文字母以及下划线等等,正则表达式规定了如何表示范围:

标识符 含义
[…] 在集合中的任一个字符
[^…] 不在集合中的任一个字符
. 出\n 之外的任一个字符
\w 所有的单字,包括字母,数字及下划线
\W 不包括所有的单字,\w 的补集
\s 所有的空白字符,包括空格,制表符
\S 所有的非空白字符
\d 所有的数字
\D 所有的非数字
\b 退格字符

结合元字符和范围,我们可以定义出很强大的模式来,比如,一个简化版的匹配 Email的正则表达是为:
    var emailval = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/;
    emailval.test("kmustlinux@hotmail.com");//true
    emailval.test("john.abruzzi@pl.kunming.china");//true
    emailval.test("@invalid.com");//false,不合法

[\w-]表示所有的字符,数字,下划线及减号,[\w-]+表示这个集合最少重复一次,然后紧接着的这个括号表示一个分组(分组的概念参看下一节),这个分组的修饰符为星号(*),表示重复零或多次。这样就可以匹配任意字母,数字,下划线及中划线的集合,且至少重复一次。

而@符号之后的部分与前半部分唯一不同的是,后边的一个分组的修饰符为(+),表示至少重复一次,那就意味着后半部分至少会有一个点号(.),而且点号之后至少有一个字符。

这个修饰主要是用来限制输入串中必须包含域名。

最后,脱字符(^)和美元符号($)限制,以„„开始,且以„„结束。这样,整个表达式的意义就很明显了。

再来看一个例子:在 C/Java 中,变量命名的规则为:以字母或下划线开头,变量中可以包含数字,字母以及下划线(有可能还会规定长度,我们在下一节讨论)。这个规则描述成正则表达式即为下列的定义:
    var variable = /[a-zA-Z_][a-zA-Z0-9_]*/;
    print(variable.test("hello"));
    print(variable.test("world"));
    print(variable.test("_main_"));
    print(variable.test("0871"));

将会打印:
true
true
true
false

前三个测试字符均为合法,而最后一个是数字开头,因此为非法。应该注意的是,test 方法只是测试目标串中是否有表达式匹配的部分,而不一定整个串都匹配。比如上例中:
    print(variable.test("0871_hello_world"));//true
    print(variable.test("@main"));//true

同样返回 true,这是因为,test 在查找整个串时,发现了完整匹配 variable 表达式的部分内容,同样也是匹配。为了避免这种情况,我们需要给 variable 做一些修改:
    var variable = /^[a-zA-Z_][a-zA-Z0-9_]*$/;

通过加推导(+),星推导(*),以及谓词,我们可以灵活的对范围进行重复,但是我们仍然需要一种机制来提供诸如 4 位数字,最多 10 个字符等这样的精确的重复方式。这就需要用到下表中的标记:

标记 含义
{n} 重复 n 次
{n,} 重复 n 或更多次
{n,m} 重复至少 n 次,至多 m 次

有了精确的重复方式,我们就可以来表达如身份证号码,电话号码这样的表达式,而不用担心出做,比如:
    var pid = /^[\d{15}|\d{18}]$/;//身份证
    var mphone = /\d{11}/;//手机号码
    var phone = /\d{3,4}-\d{7,8}/;//电话号码
    mphone.test("13893939392");//true
    phone.test("010-99392333");//true
    phone.test("0771-3993923");//true