第8章 使用正则表达式

第8章 使用正则表达式

正则表达式(Regular Expression)是一个描述字符模式的对象,其中字符模式由普通字符(如A~Z、a~z、0~9)和特殊字符(元字符)组成。正则表达式是高效的字符串检索和处理工具,在网页设计中占据重要位置。


JavaScript的RegExp类表示正则表达式,String和RegExp对象都定义了支持正则表达式的方法,后者使正则表达式具备强大的模式匹配和文本检索与替换功能。本章首先介绍用以描述“字符模式”的正则表达式语法,随后介绍使用正则表达式的String和RegExp方法,以及实战开发技巧。


【学习重点】


▲ 定义正则表达式


▲ 熟悉正则表达式基本规则


▲ 熟练使用正则表达式匹配模式


▲ 使用RegExp对象


▲ 灵活使用正则表达式操作字符串


8.1 认识正则表达式


ECMAScript 3.0版本对JavaScript正则表达式进行了标准化。JavaScript 1.2版本实现了ECMAScript 3.0版要求的正则表达式特性的子集,JavaScript 1.5版本实现了完整的标准。


JavaScript正则表达式以Perl正则表达式为基础,其中JavaScript 1.2版本实现了Perl 4版本的正则表达式,JavaScript 1.5版本实现了Perl 5版本的正则表达式的大型子集。


JavaScript不支持Perl正则表达式的语法特征如下:


☑ s(单行模式)和x(扩展语法)标志。


☑ \a、\A、\e、\E、\l、\L、\u、\U、\Q、\z、\Z、\G转义序列。


☑ (?<=正后向声明、(?


☑ (?<#注释。


☑ (?扩展语法。


在正则表达式中,匹配是最基本的行为,它描述了正则表达式的运算结果。使用正则表达式从给定字符串中查找出符合匹配模式的子字符串,也可能会存在多处符合匹配模式的子字符串,这时每一个子字符串就称为一个匹配。


在网页设计中,正则表达式的应用比较广泛,具体说明如下。


☑ 验证字符串。验证给定的字符串或子字符串是否符合指定特征,例如,验证邮件地址、电话号码等用户提交的数据是否合法等。


☑ 查找字符串。从指定的文本中查找符合指定特征的字符串。


☑ 替换字符串。把给定字符串中符合指定特征的子字符串替换为其他字符串。


☑ 提取字符串。从给定的字符串中提取符合指定特征的子字符串。


8.2 定义正则表达式


定义正则表达式的方法包括构造法和直接量,下面分别进行介绍。


8.2.1 构造正则表达式


JavaScript通过内置的RegExp对象实现对正则表达式的支持。RegExp是Regular Expression(规则表达式)短语的简写,它表示正则表达式的意思。


RegExp对象是一个构造函数,该函数可以带一个或两个参数,用来构造正则表达式。第一个参数指定了正则表达式的匹配模式,第二个参数为可选参数,用来修饰或限制匹配模式,即指定执行匹配操作的方式。


【示例1】先看一个简单的示例。



第8章 使用正则表达式

这是一个最简单的正则表达式,匹配模式为一个字符"a",即该正则表达式能够匹配指定字符串中的字符"a"。由于没有修饰词(即没有设置第二个参数),所以这个正则表达式只能够匹配字符串中第一个小写字母a。



第8章 使用正则表达式

上面示例定义的正则表达式仅能够匹配字符串"JavaScript!=JAVA"中下标为1的字符a,后面的字母a将无法被匹配到。


【示例2】如果希望该正则表达式匹配字符串中所有的字母a,且不区分大小写,则可以在第二个参数中增加g和i修饰词。



第8章 使用正则表达式

然后测试:



第8章 使用正则表达式


提示:在正则表达式中,JavaScript主要支持“g”、“i”和“m”3个修饰性字符。具体说明如下。


☑ 字符“g”是global(全局)一词的缩写,即用来指定全局匹配,通俗地说就是正则表达式将在指定字符串范围内执行所有匹配查找,而不是仅仅找到第一个匹配后就立即停止检索。


☑ 字符“i”是case-insensitive(大小写不敏感)短语中insensitive一词的缩写,即执行不区分大小写的匹配,也就是说对于字母大小写视为等同。


☑ 字符“m”是multiline(多行)一词的缩写,即设置匹配模式能够在多行字符串中执行操作。



这3个修饰词分别指定了匹配操作的范围、大小写和多行行为。这些关键词可以*组合,以字符串的形式传递给Regular()构造函数。


在ECMAScript标准化之前,JavaScript不支持m修饰词,后来才提供支持。另外,JavaScript不支持的修饰词包括x(设置空格匹配问题)、e(设置逆向匹配问题)、s(设置点号匹配问题)等。


【示例3】RegExp()构造函数的第一个参数是一个字符串或者一个正则表达式,该参数构成了正则表达式的匹配主体。如果该参数是一个字符串,则可以是一个符合正则表达式规则的字符串。



第8章 使用正则表达式

在上面示例中,字符串"\b\w"是一个匹配模式,其中反斜杠表示转义序列,双反斜杠表示斜杠本身的意思,而\b又表示单词的边界,\w表示任意ASCII字符,所以上面的正则表达式将匹配字符串"JavaScript JAVA"中每个单词的首字母。


因为无论是字符串直接量,还是正则表达式都使用字符\表示转义序列,所以将正则表达式作为字符串直接量传递给RegExp()构造函数时,必须使用“\”替换所有“\”字符。



提示:当要动态创建一个正则表达式,而不能使用正则表达式直接量的语法来表示时,构造函数RegExp()非常有用。例如,如果检索的字符串是由用户输入的,那么就必须在运行时使用RegExp()构造函数来创建正则表达式。



【示例4】如果RegExp()构造函数的第一个参数是一个正则表达式,则第二个参数可以省略。这时RegExp()构造函数将使用与正则表达式参数相同的匹配模式和修饰词创建一个新的RegExp对象。



第8章 使用正则表达式

可以把正则表达式直接量传递给RegExp()构造函数,对正则表达式进行类型封装。


【示例5】RegExp()可以作为普通函数进行调用。作为普通函数,RegExp()函数的行为与使用new运算符调用构造函数时一样。不过如果函数的参数是正则表达式,那么它仅返回正则表达式,而不再创建一个新的RegExp对象。



第8章 使用正则表达式

8.2.2 正则表达式直接量


JavaScript约定在正则表达式直接量中,双斜杠包含的字符为正则表达式的匹配模式,它是一组特殊的字符串,但是不能够使用引号进行包含。正则表达式的修饰词则跟随在最后一个斜杠的后面。


【示例1】在下面代码中定义一个正则表达式直接量,然后就直接进行调用。



第8章 使用正则表达式


提示:在RegExp()构造函数与正则表达式直接量语法中,匹配模式的表示是不同的。对于RegExp()构造函数来说,它接收的是字符串,而不是正则表达式的匹配模式。所以,在上面示例中,RegExp()构造函数中第一个参数中的特殊字符必须使用双反斜杠来表示,以防止字符串中每个字符被RegExp()构造函数转义。同时对于第二个参数中的修饰词也应该使用引号来包含。而正则表达式直接量中,每个字符都按正则表达式的规则来定义,普通字符与特殊字符都会被正确解释。



【示例2】在RegExp()构造函数中可以为正则表达式传递变量,而在正则表达式直接量中是不允许的。



第8章 使用正则表达式

在上面示例中,对于正则表达式直接量来说,“"”和“+”都将被视为普通字符而进行匹配,而不是作为字符与变量的语法标识符进行连接操作。


8.3 字符匹配


正则表达式的语法主要就是对各个元字符功能的描述。元字符从功能上大致分为模式匹配符、定位符与原义字符、限定符、选择匹配符、特殊字符、字符匹配符、分组组合和反向引用符等。本节先简单介绍字符匹配模式规则。


8.3.1 认识普通字符和元字符


根据正则表达式语法规则,匹配模式是由一系列字符构成的。大多数字符仅能够描述自身,这些字符被称为普通字符,如所有的字母、数字等。


【示例】普通字符只能够匹配字符串中与自身相同的字符。例如,对于字符串“JavaScript”来说,如果要查找整个字符串,需要设计如下正则表达式:



     var r=/JavaScript/;


正则表达式还规定了一系列的特殊字符,特殊字符不是按照字符自身进行匹配的,但是它们拥有特殊的语义。例如:



     (、)、[、]、{、}、\、|、^、$、?、、.


特殊字符是不能够匹配自身的。由于具有特殊的语义,所以要匹配自身,还需要进行转义。正是得益于这些特殊的字符,用户才可以设计出很多灵活、实用的正则表达式,并利用这些正则表达式匹配各种复杂的文本信息。因此,这些字符也被称为元字符。


8.3.2 字符直接量


字符的表示方法有多种,除了可以直接使用字符来表示它们本身外,还可以使用ASCII编码或者Unicode编码来表示。


1.ASCII编码

如果使用ASCII编码表示字符,则必须指定一个两位的十六进制值,并在前面增加“\x”前缀。


【示例1】下面使用ASCII编码来定义正则表达式直接量。



第8章 使用正则表达式

由于字母a的ASCII编码为97,被转换为十六进制数值后为61,因此如果要匹配字符a,就应该在前面添加“\x”前缀,以提示该组合为ASCII编码。



第8章 使用正则表达式

【示例2】除了十六进制外,还可以直接使用八进制数值来进行匹配:



第8章 使用正则表达式

使用十六进制需要添加“\x”前缀,主要是避免语义混淆,但是八进制不需要添加前缀。而对于十进制的ASCII编码值是不能够直接使用的。



注意:ASCII编码只能够匹配有限的单字节拉丁字符,对于双字节的汉字等字符是无法表示的。



2.Unicode编码

如果使用Unicode编码表示,则必须指定一个4位的十六进制值,并在前面增加“\u”前缀。


【示例3】下面使用Unicode编码来定义正则表达式直接量。



第8章 使用正则表达式

【示例4】当这些特殊的转义字符用在RegExp()构造函数中时,应注意使用双斜杠来表示。



     var r=new RegExp("\u0061");


因为,RegExp()构造函数会把“\u”解释为字符u本身,所以对于“\u0061”编码来说,在构造的正则表达式中就成为了“u0061”,从而失去它原来的语义。


除了这些固定的字符和转义编码外,JavaScript还支持一些特殊的字符,如表8-1所示。



表8-1 JavaScript中的特殊字符


第8章 使用正则表达式

对于这些特殊字符,如果在RegExp()构造函数中使用,则必须使用双反斜杠进行转义。对于元字符来说,如果要使用字符本义,则需要添加反斜杠前缀进行转义。例如:



     (、)、\ [、]、{、}、\、|、^、$、?、*、.


表示的语义分别是这些元字符本身,此时它们就不再拥有特殊的语义:



     (、)、[、]、{、}、\、|、^、KaTeX parse error: Double subscript at position 105: …9787302421924_8_̲1_2_5"><span>8.…与正则表达式中子表达式的编号来引用这些临时属性。其中属性$1标识符指向第一个值引用,属性$2标识符指向第二个值引用,依此类推。

【示例3】可以直接在定义分组的表达式中包含反向引用。这可以通过使用特殊转义序列(如\l、\2等)来实现(详细内容可以参阅8.5.2节内容)。



第8章 使用正则表达式

在上面示例的正则表达式中,“\1”表示对第一个反向引用(\w)所匹配的字符a引用,“\2”表示对第二个反向引用(\w)所匹配的字符b引用,“\3”表示对第二个反向引用(\w)所匹配的字符c引用。


【示例4】可以在字符串对象的replace()方法中使用。通过使用特殊字符序列$1、$2、$3等来实现。例如,在下面的示例中将颠倒相邻字母和数字的位置:



第8章 使用正则表达式

在上面例子中,正则表达式包括两个分组,第一个分组匹配任意连续的字母,第二个分组匹配任意连续的数字。在replace()方法的第二个参数中,$1表示对正则表达式中第一个子表达式匹配文本的引用,而$2表示对正则表达式中第二个子表达式匹配文本的引用,通过颠倒$1和$2标识符的位置,即可实现字符串的颠倒替换原字符串。


8.5.4 案例:非引用型分组


正则表达式分组会占用一定的系统资源,在较长的正则表达式中,存储反向引用会降低匹配速度。但是很多时候使用分组仅是为了设置操作单元,而不是为了引用,这时建议选用一种非引用型分组,它不会创建反向引用。


【示例】通过使用非引用型分组,既可以拥有与匹配字符串序列同样的能力,又不用存储匹配文本的开销。创建非引用型分组的方法是,在左括号的后面分别加上一个问号和冒号。



第8章 使用正则表达式

此时如果调用RegExp对象的$1标识符来引用分组匹配的文本信息,结果会返回一个空字串,因为该分组是非引用型的。



第8章 使用正则表达式

正因为如此,字符串对象的replace()方法就不能通过RegExp.$1变量来使用任何反向引用,或在正则表达式中使用它。


非引用型分组对于必须使用子表达式,但是又不希望存储无用的匹配信息而浪费系统资源,或者希望提高匹配速度,是非常重要的方法。


8.5.5 选择


当正则表达式执行匹配操作时,经常会遇到选择性问题。


【示例1】下面的示例演示了选择匹配模式的设计方法。


如果希望匹配字符串"abc",同时还要匹配字符串"123"。由于这两个字符串完全没有相同的字符,按照前面介绍的方法,需要编写两个不同的正则表达式,并分别对两个字符串进行匹配:



第8章 使用正则表达式

也可以使用字符范围类,实现相同的匹配选择操作。



第8章 使用正则表达式

在正则表达式的字符范围类中,把两个匹配模式分别包含在小括号语法分隔符,组成两个独立的子表达式,并通过范围类进行匹配操作。不过,这种方式的执行效率比较低,正则表达式会为不同的子表达式开辟内存空间,这样就占用了不必要的系统资源。


【示例2】JavaScript正则表达式提供对选择操作符的支持,选择操作符使用管道符(|)表示,它放在两个独立的单元之间,表示对多个单元执行选择匹配操作。



第8章 使用正则表达式

针对上面的示例,如果使用选择操作符,则可以这样设计:



第8章 使用正则表达式

【示例3】可以设计多重选择模式,这时只需要在多个连续的单元之间加入选择操作符即可,执行连续选择匹配操作。



第8章 使用正则表达式

【示例4】选择操作符在实际开发中经常会被使用。例如,针对提交的表单信息进行敏感字符过滤,这时可以设计一个匹配所有敏感字符的正则表达式,然后使用字符串对象的repalce()方法把所有敏感字符替换为字符编码,并转换为网页显示的编码格式。



第8章 使用正则表达式

最后,把JavaScript正则表达式的分组、引用和选择元字符进行小结,以方便读者比较参考,如表8-4所示。



表8-4 JavaScript正则表达式的分组、引用和选择元字符


第8章 使用正则表达式

8.5.6 声明


声明包括正前向声明和反前向声明两种模式。


☑ 正前向声明:这里的前向是指定匹配模式后面的字符,声明表示条件的意思,也就是指定在接下来的字符必须被匹配,但并不真正进行匹配。正前向声明使用“(?=匹配条件)”来表示。


【示例1】下面的代码定义了一个正前向声明的匹配模式。



第8章 使用正则表达式

在上面示例中,通过使用(?==)锚定条件,指定只有在\w所能够匹配的字符后面跟随一个等号字符,才能够执行\w匹配。所以,最后匹配的是字符b,而不是字符a。


☑ 反前向声明,与正前向声明匹配相反,指定接下来的字符都不必匹配。反前向声明使用“(?!匹配条件)”来表示。


【示例2】下面的代码定义了一个反前向声明的匹配模式。



第8章 使用正则表达式

在上面示例中,通过使用(?!=)锚定条件,指定只有在“\w”所能够匹配的字符后面不跟随一个等号字符,才能够执行\w*匹配。所以,最后匹配的是字符a,而不是字符b。



提示:声明虽然包含在小括号内,但这不是分组。事实上,分组不会考虑声明的存在。对于正则表达式来说,它们仅是一个修饰性限定条件,而不是可引用的单元。



此时如果调用RegExp对象的KaTeX parse error: Double subscript at position 519: …9787302421924_8_̲1_2_19"><span>8…能够使模式定位在字符串的末尾。JavaScript支持的锚记如表8-6所示。



表8-6 JavaScript支持的锚记


第8章 使用正则表达式

8.5.9 标志


正则表达式的标志说明了高级模式匹配的规则。与其他的正则表达式语法不同,标志是在模式分隔符“/”之外进行说明的,它不会出现在模式分隔符(即两个斜杠)之间,而是位于第二个斜杠之后。JavaScript正则表达式支持的标志包括3种,说明如表8-7所示。



表8-7 JavaScript正则表达式支持的标志


第8章 使用正则表达式

表8-7中的3个标志可以任意混合使用。


【示例1】如果把标志i与g混合使用,就可以执行一个全局的、大小写不敏感的匹配。如下:



     var r=/JavaScript/gi;


上面的模式可以匹配指定字符串中所有的“JavaScript”、“JavaScript”、“JavaScript”、“JavaScript”或“JavaScript”等不同大小写字符串。


如果字符串中包含很多行,字符匹配就比较复杂。在JavaScript 1.5版本以前,由于不支持m标志,为了实现多行匹配,需要使用split()方法将字符串分割成行与行的数组,然后再对每一行单独进行正则表达式测试。


【示例2】在本示例中,只能够匹配最后一个字母c,但是前面两个字母没有被匹配,因为只有字母c在字符串的结尾处:



第8章 使用正则表达式

由于字符串s中有两个换行符,如果匹配每一行结尾的字母,则需要使用多行匹配模式:



第8章 使用正则表达式


提示:多行模式会改变边界的匹配行为,这时KaTeX parse error: Double subscript at position 121: …9787302421924_8_̲1_6"><span>8.6 …_属性来说,它符合JavaScript标识符语法规范,因此可以直接使用。


【示例3】针对上面示例也可以这样设计。



第8章 使用正则表达式

这些属性的值都是动态的,每次执行exec()或test()方法时,所有属性值都会被重新设置。


【示例4】在本示例中,第一次执行匹配和第二次执行匹配时,这些静态属性值都会实时动态更新。



第8章 使用正则表达式

通过上面示例可以看出,RegExp静态属性是公共的,对于所有正则表达式对象来说都可以访问。


8.6.3 案例应用


RegExp对象定义了两个用于执行模式匹配操作的方法,如表8-10所示。它们的行为与String对象的正则表达式操作方法类似。例如,RegExp对象的exec()方法与String对象的match()方法操作相似,只不过exec()是以字符串为参数的RegExp对象方法,而match()方法是以正则表达式为参数的String对象方法。在非全局模式下,它们的返回值是相同的。



表8-10 RegExp对象的方法


第8章 使用正则表达式

1.exec()方法

在所有RegExp模式匹配方法和String模式匹配方法中,exec()方法的功能最强大。作为正则表达式的通用匹配方法,比RegExp.test()、String.search()、String.replace()和String.match()都复杂。该方法需要一个参数,用来执行要执行操作的字符串,并返回一个数组,数组中存放的是匹配结果。如果没有找到匹配,返回值为null。



第8章 使用正则表达式

exec()方法的工作机制是这样的:当调用方法时,先检索字符串参数,从中获取与正则表达式相匹配的文本。如果找到了匹配的文本,就会返回一个数组;否则,返回null。返回数组的元素具体说明如下。


☑ 第0个元素,是与表达式相匹配的文本。


☑ 第一个元素,是与正则表达式的第一个子表达式相匹配的文本(如果存在)。


☑ 第二个元素,是与正则表达式的第二个子表达式相匹配的文本,依此类推。


返回数组还包含几个属性,具体说明如下。


☑ length:该属性声明的是数组中的元素个数。


☑ index:该属性声明的是匹配文本的第一个字符的位置。


☑ input:该属性包含的就是整个字符串。


当调用非全局模式的正则表达式对象的exec()方法时,返回的数组与调用字符串对象的match()方法返回数组是完全相同的。即它们都将进行检索,并返回上述元素和属性。


当执行全局匹配模式时,exec()的行为就略有变化。这时它定义lastlndex属性,用来指定下一次执行匹配时开始检索字符串的位置。当它找到了与表达式相匹配的文本时,在匹配之后,它将把正则表达式的lastlndex属性设置为下一次匹配执行的第一个字符的位置。这就是说,可以通过反复地调用exec()方法来遍历字符串中的所有匹配文本。当exec()再也找不到匹配的文本时,它将返回null,并且把属性lastlndex重置为0。


【示例1】在本示例中,定义正则表达式直接量,用来匹配字符串s中每个字符。在循环结构的条件表达式中反复执行匹配模式,并根据返回结果的值是否为null作为循环条件。当返回值为null时,说明字符串检测完毕。然后,读取返回数组a中包含的匹配子字符串,并调用该数组的属性index和lastIndex,其中index显示当前匹配子字符串的起始位置,而lastIndex属性显示下一次匹配操作的起始位置。



第8章 使用正则表达式

实际上通过循环结构反复调用exec()方法是唯一获得全局模式的完整模式匹配信息的方法。



提示:无论正则表达式是否是全局模式,exec()方法都会将完整的细节添加到返回数组中。字符串对象的match()方法就不同,它在全局模式下返回的数组中不会包含这么多的细节信息。



2.test()方法

test()方法要比exec()方法简单,它能够检测参数字符串是否包含至少一个与当前正则表达式的匹配,如果包含匹配就返回true,否则就返回false。


【示例2】在下面示例中,方法test()就会返回true,因为在字符串s中包含很多个匹配:



第8章 使用正则表达式

同样使用下面正则表达式也能够匹配,并返回true:



第8章 使用正则表达式

但是如果使用下面这个正则表达式进行匹配,就会返回false,因为在字符串"JavaScript"中就找不到对应的匹配:



第8章 使用正则表达式

调用test()方法等价于调用exec()方法。如果exec()方法返回值不是null,则test()方法将返回true。


因此,当一个全局正则表达式调用方法test()时,它的行为与exec()方法相同,即它将从lastIndex属性值指定的位置开始验证字符串,如果发现了匹配,就会将lastIndex属性值设置为紧邻当前匹配字符串后的字符位置。因此,就可以使用test()方法代替exec()方法来遍历字符串,检测匹配的字符。


【示例3】针对exec()方法中的循环遍历匹配,可以这样设计:



第8章 使用正则表达式

【拓展】String对象定义了search()、replace()和match()方法,用来支撑正则表达式的模式匹配操作,而RegExp对象支持test()和exec()方法实现模式匹配操作。


对于search()、replace()和match()方法来说,它们返回的匹配信息没有test()和exec()方法详细。例如,test()和exec()方法支持属性lastIndex。而字符串对象的方法只是将lastIndex属性重置为0。如果使用一个全局模式的exec()方法或test()方法来检索多个字符串,那么就必须找到每个字符串中的所有匹配,以便lastIndex属性会被自动重置为0,或者必须明确地将lastIndex属性设置为0。否则,当再次检索一个新字符串时,起始位置可能就是原来的字符串中的一个任意位置,而不一定是字符串的开头。


对于test()和exec()方法来说,只有声明了g标志的正则表达式,才会发生这种特殊的lastIndex属性行为。如果正则表达式对象没有标志g,exec()和test()将忽略它的lastIndex属性。下面列表比较字符串对象和正则表达式包含的6种模式匹配的方法,如表8-11所示。



表8-11 比较各种模式匹配的方法


第8章 使用正则表达式

8.7 综合案例:设计表单验证


表单验证在网页设计中经常用到,为了方便读者学习和开发需要,本节将通过一个综合实例演示如何使用正则表达式设计一个表单验证工具Validator。本节实例会涉及后面几章有关面向对象的知识,读者可根据实际情况有选择地学习。


Validator是基于JavaScript的伪静态类和对象的自定义属性,可以对网页中的表单项输入进行相应的验证,允许同一页面中同时验证多个表单,熟悉接口代码之后也可以对特定的表单项,甚至仅是某个字符串进行验证。因为是伪静态类,所以在调用时不需要实例化,直接以“类名+语法+属性或方法名”来调用。此外,Validator还提供3种不同的错误提示模式,以满足不同的需要。


【操作步骤】


第1步,新建文档,保存为index.html。在页面中新建一个表格,设计一个表单框,其中包含多个输入文本框,如图8-1所示。



第8章 使用正则表达式

图8-1 设计表单



第2步,在标签底部插入一个<script type=“text/JavaScript”>标签,在其中设计Validator类表单验证脚本。


第3步,在脚本中新建全局对象Validator,在其中定义多个属性值为正则表达式的成员。



第8章 使用正则表达式

第4步,为Validator对象定义一个Validate()方法,该方法根据参数theForm指定的表单form,通过for循环语句获取表单中所有包含dataType属性的文本框。然后根据dataType属性值不同,分别调用第3步定义的正则表达式执行表单验证。如果通过验证,说明输入值合法,否则获取该文本框的msg属性值,并显示错误信息。



第8章 使用正则表达式


第8章 使用正则表达式

第5步,使用自定义属性dataType定义表单项(文本框)验证类型。在表单结构中,为每个文本框设置如下自定义属性:



     


其中自定义属性dataType用于设定表单项的输入数据验证类型,值为字符串,必填项目。该属性可选值如下:



第8章 使用正则表达式

可选值的验证功能说明如下。


☑ Require:必填项。


☑ Chinese:中文。


☑ English:英文。


☑ Number:数字。


☑ Integer:整数。


☑ Double:实数。


☑ Email:Email地址格式。


☑ Url:基于HTTP协议的网址格式。


☑ Phone:电话号码格式。


☑ Mobile:手机号码格式。


☑ Currency:货币格式。


☑ Zip:邮政编码。


☑ IdCard:身份证号码。


☑ QQ:QQ号码。


☑ Date:日期。


☑ SafeString:安全密码。


☑ Repeat:重复输入。


☑ Compare:关系比较。


☑ Range:输入范围。


☑ Limit:限制输入长度。


☑ LimitB:限制输入的字节长度。


☑ Group:验证单/多选按钮组。


☑ Custom:自定义正则表达式验证。


☑ Filter:设置过滤,用于限制文件上传。



提示:另外,还可以通过如下自定义属性为文本框设置特定验证需求。



☑ accept=“string”,可选。设定表单项输入过滤,多用于type="file"的上传控件,以限制允许上传的文件类型。该属性仅当dataType属性值为Filter时起作用。


☑ max=“int”。在dataType属性值为Range时必选,为Group且待验证项是多选按钮组时可选(此时默认值为1),为Limit/LimitB时可选(此时默认值为Number.MAX_VALUE的值)。当dataType属性值为Range时,用于判断输入是否在min与max的属性值之间;当dataType属性值为Group,且待验证项是多选按钮组时,用于设定多选按钮组的选中个数,判断选中个数是否在[min,max]区间;当dataType属性值为Limit时,用于验证输入的字符数是否在[min,max]区间;当dataType属性值为LimitB时,用于验证输入字符的字节数是否在[min, max]区间。


☑ min=“int”。在dataType属性值为Range时必选,为Group且待验证项是多选按钮组时可选(此时默认值为1),为Limit/LimitB时可选(此时默认值为0)。当dataType属性值为Range时,用于判断输入是否在min与max的属性值之间;当dataType属性值为Group,且待验证项是多选按钮组时,用于设定多选按钮组的选中个数,判断选中个数是否在[min,max]区间;当dataType属性值为Limit时,用于验证输入的字符数是否在[min,max]区间;当dataType属性值为LimitB时,用于验证输入字符的字节数是否在[min,max]区间。☑ msg=“string”,必选。在验证失败时要提示的出错信息。


☑ operator=“NotEqual | GreaterThan | GreaterThanEqual | LessThan | LessThanEqual | Equal”。在dataType属性值为Compare时可选(默认值为Equal)。


各选值所对应的关系操作符如下。


▶ NotEqual:不等于!=。


▶ GreaterThan:大于>。


▶ GreaterThanEqual:大于等于>=。


▶ LessThan:小于<。


▶ LessThanEqual:小于等于<=。


▶ Equal:等于=。


☑ require=“true | false”,可选。用于设定表单项的验证方式。当值为false时,表单项不是必填项,但当有填写时,仍然要执行dataType属性所设定的验证方法,值为true或任何非false字符时,可省略此属性。


☑ to=“sting | int”。当dataType值为Repeat或Compare时必选。当dataType值为Repeat时,to的值为某表单项的name属性值,用于设定当前表单项的值是否与目标表单项的值一致;当dataType的值为Compare时,to的选值类型为实数,用于判断当前表单项的输入与to的值是否符合operator属性值所指定的关系。


☑ format=“ymd | dmy”。在dataType属性值为Date时可选(默认值为ymd)。用于验证输入是否为符合format属性值所指定格式的日期。符合规则的输入示例如2015-11-23、2015/11/23、15.11.23、23-11-2015等。注意,当输入的年份为2位时,如果数值小于30,将使年份看作处于21世纪,否则为20世纪。


☑ regexp=“object”。在dataType属性值为Custom时必选,用于验证输入是否符合regexp属性所指定的正则表达式。


第6步,调用Validate()方法进行验证。在提交按钮中绑定Validate()方法,代码如下:



     




在调用Validate()方法中,第一个参数为需要验证的表单对象,第二个参数为模式。这个模式指定要显示错误信息的方式,效果如图8-2所示。



第8章 使用正则表达式

图8-2 表单错误提示信息