首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

14.5  简单模式

要精确地构造所需的正则表达式是一件不容易的事情。灵活运用正则表达式,必须充分了解正则表达式的构造语法。而正则表达式的语法主要是对正则表达式各个元字符功能的描述,接下来的两节将详细描述各个元字符的功能。根据其复杂程度,正则表达式可以分为简单模式和复杂模式。其中,简单模式包括普通字符、特殊字符、字符类以及量词等。

 14.5.1  普通字符

普通字符可以是字母、数字、汉字、下划线,以及没有特殊定义的标点符号等。表达式中的普通字符,在匹配一个字符串时,匹配与之相同的字符。

如正则表达式/abc/,abc由普通字符构成。在匹配时,只要在匹配字符串中出现“abc”,即可成功匹配。

特别指出的是,如果是在表达式中表示特殊意义的字符,如“*”、“+”、“{”、“(”、“)”等(这些都有特殊含义,将在下面的章节中解释),那就要在前面加转义符“\”。例如要匹配字符“*”,正则表达式就要写成:/\*/。转义符的特殊字符汇总如表14.4所示。

表14.4  需要用转义符的特殊字符表

字符

^

$

(

)

{

}

+

*

.

?

|

[

]

表示

\^

\$

\(

\)

\{

\}

\+

\*

\.

\?

\|

\[

\]

到此,有些读者可能要问,如何匹配转义符“\”呢?确实,转义符“\”也是一个很特殊的字符,而且在显式构造和隐式构造中表示形式也不相同。

如果正则表达式中要匹配原义字符“\”,并且用隐式构造法,那么模式文本中要以“\\”来表示:

var re=/\\/;

若使用显式构造法,因为JavaScript中的字符串的转义字符也是“\”(请参考String对象相关知识),所以必须使用“\\\\”来表示原义字符“\”,如下代码所示。

var re = new RegExp("\\\\");

注意:由于JavaScript中字符串的转义字符也是“\”,所以用显式构造法去创建正则表示式时,如果用到后面的特殊字符或者字符类,如“\d”,就要多加一个“\”,如var re= new RegExp("\\d{5}")正确,而var re1 = new RegExp("\d{5}")则错误。

 14.5.2  特殊字符

一些不便书写的特殊字符,如回车换行符、制表符等,也采用在前面加“\”的方法来表示。特殊字符汇总如表14.5所示。

表14.5  特殊字符表

字符

\t

\n

\r

\f

\a

\e

\v

\0

描述

制表符

换行

回车

换页

alert字符

escape字符

垂直制表符

空字

这些特殊的字符还包括:

— “\xn”:匹配ASCⅡ码值等于n的字符,n必须是两位的十六进制整数,如“\x65”表示字符A,而\x97表示字符a。

— “\un”:匹配Unicode编码等于n的字符,n必须是一个4位的十六进制整数。

— “\cX”:匹配X对应的控制字符,如“\cM”表示Ctrl+M表示的控制字符。

 14.5.3  字符类

字符类包括:简单类、反向类、范围类、组合类以及预定义类。

简单类:用方括号“[]”来表示单个字符“或”的关系,匹配方括号内任意一个字符。例如正则表达式/[123]/可以匹配“1”、“2”、“3”中的任意一个字符。

注意:如果方括号[]中需要匹配字符“]”,则需要把“]”放在字符串的首位,并加转义符“\”,写成/[\]123]/的形式。

反向类:[^]用来匹配不在括号内的任意字符,恰与简单类相反,故称为反向类。例如表达式/[^abc]/,不匹配“a”、“b”或“c”,可以匹配除这三个字符外的其他任意字符。

注意:绝对不能大意写成/^[]/,那“^”就变成后面要介绍的定位符,表示匹配以括号中任意字符开头的字符串。书写正则表达式一定不可粗心大意。

范围类:[x-y]用来表示一个匹配范围x到y,即可匹配从x到y的任意字符。最常用的就是查找从a到z的任意字符,其表达式可以写成/[a-z]/;匹配任意的数字,表达式可写成/[0-9]/。

范围类可以和反向类结合使用,如表达式/[^a-z]/可以匹配除了a-z范围外的其他任意字符。

注意:如果还要在范围类中匹配“-”字符,那么就应该放在x前或者y后,写成/-x-y/或者/x-y-/。

组合类:即简单类、反向类以及范围类的组合。例如表达式/[a-z0-9\.]/可以匹配a-z的任意字符,也可以匹配0-9的任意数字,还可以匹配特殊字符“.”。

注意:类不能嵌套,即不支持联合类和交叉类。例如:联合类/a-m[p-z]/和交叉类/a-m[^b-e]/在JavaScript中都是非法的。

在JavaScript中,有些常用的类,比如数字、单词字符等,用上面的组合类也能定义,但是定义和使用都很不方便,所以预先做了定义,称为预定义类。

预定义类包括:点. 、\d 、\D 、\s 、\S 、\w 、\W。它们的等价组合类,以及描述汇总情况如表14.6所示。

表14.6  预定义类表

预定义类

等价的组合类

匹配描述

.

[^\n\r]

除了换行和回车之外的任何字符

\d

[0-9]

数字

\D

[^0-9]

非数字

\s

[ \t\n\x0B\f\r]

空白字符,包括空格、制表符、制页符等

\S

[^ \t\n\x0B\f\r]

非空白字符

\w

[a-zA-Z_0-9]  

单词字符(字母、数字、下划线)

\W

[^a-zA-Z_0-9]

非单词字符(即非字母、数字或者下划线)

源程序14.8检验用户名是否有效:有效的用户名包含以字母或数字开头,加单词字符,并以数字结尾的子字符串。正则表达式可以表示为/[a-z0-9]\w\d/,若用户输入的字符串能找到正则表达式的匹配,则用户名有效并通过检验,否则用户名无效并弹出警告框。

//源程序14.8

<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.0//EN"

"http://www.w3.org/TR/REC-html140/strict.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<title>Sample Page!</title>

<script language="JavaScript" type="text/javascript">

<!--

function test_zifulei(obj)

{

  var username=obj.username.value;

  var regx=/[a-z0-9]\w\d/g

  //不包含规定字符,用户名无效

  if(!regx.test(username))

  {       

    alert("\n用户名检测 : \n\n结果 : 用户名不合法! \n");

    obj.username.focus();

  }

  else 

    alert("\n用户名检测 : \n\n结果 : 用户名合法! \n");

}

-->

</script>

</head>

<body>

<center>

<p>

  用户名合法性检测程序

</p>

<p>

  规则:英文字符串+数字

</p>

<form onSubmit="return test_zifulei(this);">     

  <input type="text" name="username" value="yangshuiqing">

  <input type="submit" value="合法性检测">

</form>

</center>

</body>

</html>

程序运行后,结果页面如图14.13所示。

输入用户名“yangshuiqing”,不能成功匹配正则表达式/[a-z0-9]\w\d/,则用户名非法,弹出警告框如图14.14所示。

输入用户名“yangshuiqing123”,成功匹配正则表达式/[a-z0-9]\w\d/,则用户名合法,弹出警告框如图14.15所示。

             

图14.13  原始页面            图14.14  用户名“yangshuiqing”   图14.15  用户名“yangs-

不能匹配正则表达式             huiqing123”有效

 14.5.4  量词

英文中量词是用来表示个数,单数用a或者an,复数用these或者those。在正则表达式中,量词也是用来限制某些匹配字符个数的,所以也称为限定符。

正则表达式的量词表示形式总结如表14.7所示。

表14.7  量词表

  

   

   

*

出现0次或连续多次

/a*b/可以匹配“b,aab,aaab...

+

出现至少一次

/a+b/可以匹配“ab,aab,aaab...

出现0次或者一次

/a[cd]?/可以匹配“a,ac,ad

{n}

连续出现n次(=n

/\d{2}/ 相当于“\d\d”;“b{5}”相当于“bbbbb

{n,}

连续出现至少n(>=n)

/\w\d{2,}/可以匹配“a12,b456,c54786...

{n,m}

连续出现至少n次,至多m(>=n,<=m)

/ba{1,3}/可以匹配“ba”或“baa”或“baaa

量词之间可以互相等价表示,如?={0,1}、*={0,}、+={1,},读者可以自行选择,但以书写简洁为原则。正则表达式之间是互通的,所以任何正则表达式的写法是不唯一的。

量词往往在一个表达式中联合使用,再来看些例子。

正则表达式/\$\d+\.?\d*/可以匹配带$开头的物品价格。当字符串为“猪肉的价格为$13.5”时,那么该正则表达式就能正确地匹配$13.5。

再如正则表达式/\d{3}-\d{7-8}/可以匹配像020-1578964 或者 021-84579654这样开头是三位后面跟着七位或八位数字的字符串,类似于表示电话号码的正则表达式,但不精确,学习“候选符”相关内容后再来精确表示电话号码的正则表达式。

在上面量词的介绍中,除了量词{n}外,其他量词匹配的次数都是不精确的。正则表达式在模式匹配时,就出现了返回最多的匹配还是最少的匹配的问题,为此,正则表达式引入贪婪和非贪婪两种匹配模式,下面分别予以介绍。

 14.5.5  贪婪模式

根据匹配字符串以及表达式尽可能多地进行匹配,称为贪婪匹配模式,简称贪婪模式。正则表达式的默认匹配模式为贪婪模式。

例如,正则表达式为/a\d+/,匹配字符串为“a154222222”,则/d+匹配完整的154222222,虽然它也可以只匹配其中的一部分,如15422。

再如,正则表达式/fo{2,}/,匹配字符串为“fooooood”,那么o{2,}就会匹配完6个“o”,虽然它也可以只匹配2个或者4个“o”。

 14.5.6  非贪婪模式

与贪婪模式相对应,根据匹配字符串以及表达式尽可能少地进行匹配,称为非贪婪匹配模式,简称非贪婪模式。

其使用方法就是在修饰匹配次数的特殊符号后再加上一个“?”号,如“*?”、“+?”、“{n,}?”、“{n,m}?”,当然在量词{n}后加“n”也可以,但意义不大。值得注意的是,并没有在量词“?”后面加“?”的写法。

例如正则表达式为/a\d+?/,匹配字符串为“a154222222”,那么其中的/d+就只匹配子串“1”;再如正则表达式/fo{2,}?/,匹配字符串为“fooooood”,那么其中的o{2,}就只匹配子串“oo”。

 14.5.7  简单模式综合举例

在实际应用中经常需要验证手机号码的合法性,一般使用正则表达式/^(\+86)?13\d{9}$/来检验。考虑以“13”开头的手机号码,同时如果跨中继站时需加“+86”(cn)。至于新号段“158”和“159”,可扩展以上正则表达式进行检验。程序代码如源程序14.9所示。

//源程序14.9

<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.0//EN"

"http://www.w3.org/TR/REC-html140/strict.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<title>Sample Page!</title>

<script language="JavaScript" type="text/javascript">

<!--

//使用正则表达式验证手机号码

function isMobil(obj)   

{  

  var str=obj.mobilenum.value;

  var patrn=/^(\+86)?13\d{9}$/;

  var msg="\n使用正则表达式验证手机号码 :\n\n";

  msg+="手机号码 : " +str+"\n";

  if (!patrn.exec(str))

  {

     msg+="验证结果 : 手机号码不合法!\n";

     alert(msg);

     return false;

  }

  else

  {

    msg+="验证结果 : 手机号码合法!\n";

    alert(msg);

    return true;

  }  

}

-->

</script>

</head>

<body>

<br>

<center>

<p>

  使用正则表达式验证手机号码合法性

</p>

<form onSubmit="return isMobil(this);">   

  <input type="text" name="mobilenum">

  <input type="submit" value="确定">

</form>

</center>

</body>

</html>

程序运行后,在原始页面的文本输入框内输入“13548968549”或“+8613548968549”,弹出“手机号码合法!”的警告框,如图14.16所示。

如果输入“+10013548968549”等格式不正确的手机号码,则弹出“手机号码不合法!”的警告框,如图14.17所示。

             

图14.16  输入正确格式的手机号码              图14.17  输入格式错误的手机号码

在实际应用中,还可以根据目标手机号码的各小段信息判断该手机号码的归属地、号码类型等信息,并返回更为丰富的结果。同样,可先提取目标电话号码中的国家代码(如中国为+86),然后根据该代码判断手机号码所属的国家。

注意:在正则表达式/^(\+86)?13\d{9}$/中,^与$是定位符,起到开头结尾匹配作用,将在第14.6.7节中详细介绍。而(\+86)?表示“+86”字符串可以出现0次或1次,也将在第14.6.1节中详细介绍。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论