在Web上,正则表达式常用来在发送数据到服务器之前对用户的输入进行验证。毕竟,这个是JavaSrcipt诞生的原因。本节介绍两个常用的验证模式:验证日期和验证邮箱地址。
(一) 验证日期
对于大多数Web开发人员来说,日期确实是一个很头疼的问题。先不管时髦的基于层的日历系统,用户其实就想能够直接输入一个日期。大部分开发人员很怕让用户手工输入日期。现在多家使用多种不同的方法,更不要说国际化的月份和日期的名称!很多网站用三个表单字段来输入日期条目。通常有两个组合框(一个是月份,另一个是月份中的日),然后还有一个用于输入年份的文本框。尽管这个方法是可行的,但是用户依然希望能直接输入日期,这可比在三个字段中切换 并把鼠标称上称下来直接查找选择条目要方便得多。
Date.parse(),它可以将几种字符串模式转换成日期的毫秒表示。如果想让用户以dd/mm/yyyy的格式输入日期的话,要怎么办呢?当然,可以借助正则表达式。
要了解其中一个模式,先想想不同的日期表现格式。例如 ,月份一般是两个数字,从01~12;而天数一般也是两个数字,从01~31。所以,月份和天数必须是两个数字,而年份必须是四位数。现在我们写一个简单的模式:
var reDate=/\d{1,2}\/\d{1,2}\/\d{4}/
这个模式基本匹配格式dd/mm/yyyy,但并没有考虑到月份和天数的有效范围。所以,错误的结果,如55/44/2001,也可以匹配成功。要解决这个问题,要先考虑仅仅匹配天数的模式:第一个数字只能是0~3,第二个数字可以是0~9的任意数字。于是,天数的比较符合逻辑的模式应该如下:
var reDay=/[0-3]?[0-9]/;
然而这个表达式还匹配了32~39,这也是不可能出现的日期。通过使用候选项和字符类,就可以得到几乎没有漏洞的日期模式:
var reDay=/0[1-9]|[12][0-9]|3[0-1]/;
现在这个正则表达式可以正确匹配所有天数值,0也可以出现在1~9之前,但不能出现
两个0,或者数字由1和2开头的后面可以带任何0~9的数字。最后,如果天数由3开头,后面只能有0或1。接下来,让我们处理月份。
月份的情况和天数有点像,模式也类似,除了少了很多选项:
var reMonth=/0[1~9]1[0~2]/;
这个模式可以匹配01~12的所有数字。还可以限制年份在某年到某年之间,例如限制在1900~2099年之间,则年份用正则表达式可以表示为:
var reYear=/19|20\d{2}/;
那么,将以上三个天数、月份、年份的模式组成起来,就成了:
var reDate=/(?:0[1-9]|[12][0-9]|3[01]\/(?:)[1-9]|1[0-2]\/(?:19|20\d{2}))/;
注意整个模式是将日期的每个部分放入非捕获性分组中,这是为了确保可选项不会相互冲突。可以把这个正则表达式封装成函数isValidDate()并进行测试:
function isValidDate(sText){
var reDate=/(?:0[1-9]|[12][0-9]|3[01]\/(?:)[1-9]|1[0-2]\/(?:19|20\d{2}))/;
return reDate.test(sText);
}
alert(isValidDate(“5/5/2010”)); outpus “true”
alert(siValidDate(“10/22/2010”)); outpus “true”
(二) 验证电子邮件地址
创建模式来匹配所有有效的电子邮件地址确实是一个大事业。定义有效的电子邮件地址的标准是RFC2822,它定义以下的一些模式是合法的:
john@somewhere.com
john.doe@somewhere.com
john Doejohn.doe@somewhere.com
“john.doe”@somewhere.com
John@[10.1.3.1]
然而,实际上,一般只会看到前三种变体,且只有前两种才是用户会输入到网站(或Web应用)上的文本框中的。现在只讨论前两种模式的验证。
电子邮件地址的基本格式,是一串字符(可以是数字、字母、横线、点等等,除了空格,),跟着at(@)符号,最后还有一些字符。在@之前至少有一个字符,其后必须至少有三个字符,这三个字符中第二个还必须是一个句号(a@a.b是有效的地址,而a@a和a@a.都是无效的)。
@前后的文本必须符合同样的规则:不能以句号开始或结束,且不能还有两个句号连续出现,因此,正则表达式如下:
var reEmail=/^(?:\w+\.?)*\w+@(?:\w+\.?)*\w+$/;
这个表达式以非捕获性分组(?:\w+\.?)开始,它告诉你任何数量的单词字符可以跟零个或一个问号。这一部分可能出现零次或多次(a.b.c.d),所以对这个分组使用星号。
表达式下面一部分是\w+@,这保证在@之前至少有一个单词字符。然后紧跟一个非捕获性分组(?:\w+\.),它可以出现一次或多次,所以使用加号。表达式最后一部分\w+$,表示一行的最后的字符必须是一个单词字符,不允许出现类似jone@doe.之类的地址。
最后把这个模式封装到一个函数中就可以了:
function isValidEmail(sText){
var reEmail=/^(?:\w+\.?)*\w+@(?:\w+\.?)*\w+$/;
return reEmail.test(sText);
}
alert(isValidEmail(“shenmiweiyi@163.com_”); //outputs “true”
alert(isValidEmail(“shenmiweiyi@163com._”); //outputs “false”