Regular Expressions是在 UNIX 世界中发展出来的字符串比对技巧,其基本概念是用一套简单的符号来比对字符串,并可对符合比对条件的字符串进行修改或其它运算。事实上,UNIX 的许多软件或指令都支持正规表示法,例如 grep、sed、awk、ed、vi、emacs 等
JavaScript 的正规式(Regular expressions)是一个内建的对象,其建构函示(Construction functoin)为 RegExp,典型用法如下:
var re = new RegExp("pattern", "flag")
上述用法也可以写成: var re = /pattern/flag
其中,pattern 代表以正规表示法来显示的字符串,flag 则是比对的方式。
flag 的值,分别解释如下:
g:全域比对(Global match)
i:忽略大小写(Ignore case)
gi:全域匹配并忽略大小写
m:以多行模式执行匹配
mi:以多行模式执行匹配并忽略大小写
注意事项以 RegExp(pattern, flag) 的方式来建立正规式对象时,若 pattern 包含以反斜线开头的特殊字符(例如 /d、/w、/s 等)时,我们必须再加上一个反斜线来保留其特殊意义。例如: re = //d+/s/w+/g
以 RegExp 为主的等效表示法为: re = new RegExp("//d+//s//w+"+, "g");
举例来说,我们的身份证字号的格式是由一个大写英文字母加上九个数字组合而成,我们利用 onBlur 事件来进行正规式的比对,换句话说,当使用者填完资料,要离开此字段的时候,JavaScript 即会测知 onBlur 事件,并呼叫函数 checkID() 来对填入的数据进行验证。相关原始码如下:
<SCRIPT>
function checkID(formElement)
{
var re = /^[A-Z]/d{9}$/;
if (!re.test(formElement.value))
alert("你的身份证号码格式不对!");
}
</SCRIPT>
<FORM>身份证字号:<INPUT οnblur=checkID(this) value=A000000000>(第一个英文字母需大写) </FORM>
在上述原始码中,/^[A-Z]/d{9}$/ 就是一个正规式,[A-Z] 代表由 A 至 Z 的所有可能英文字母,/d 代表由 0 至 9 的数目字(事实上也可以写成 [0-9]),{9} 则代表需要有九个数目字,^ 代表字符串开始位置,$ 代表字符串结束位置,因此 /^[A-Z]/d{9}$/ 就代表可以比对身份证字号的正规式。formElement.value 代表使用者输入的字符串,
re.test() 则会传回 true 或 false,代表比对是否成功。若要不限定是大写英文字母,只需将正规式改成 /^[a-zA-Z]/d{9}$/g 就可以了!(注意:若不加入 ^ 和 $,那么 /[A-Z]/d{9}/ 就会比对到其它不合法的身份证字号,例如 AGF123456789 或是 F1234567890 等。因此,加入 ^ 和 $ 可保证比对正确的字符串一定是由由一个大写英文字母加上九个数字所构成。)
事实上,身份证字号本身就有内在的编码规则,这些规则和使用者的性别有关,因此若要实现较完整的窗体验证,就必须应用较完整的身份证编码规则。
另一个简单的例子,是要求使用者输入信用卡号码,这是一组16个数字的号码,例如:
信用卡号码:(格式:xxxx-xxxx-xxxx-xxxx) 当 onBlur 发生时,换句话说,JavaScript 会呼叫函数 checkCreditCard( ) 来对填入的资料进行验证。相关原始码如下:
<SCRIPT>
function checkCreditCard(control)
{
var re = /^/d{4}-/d{4}-/d{4}-/d{4}$/;
if (!re.test(control.value))
alert("你的信用卡号码不符合「xxxx-xxxx-xxxx-xxxx」的格式!");
}
</SCRIPT>
<FORM>信用卡号码:<INPUT οnblur=checkCreditCard(this) value=xxxx-xxxx-xxxx-xxxx>(格式:xxxx-xxxx-xxxx-xxxx) </FORM>
在上例中,很显然地,/^/d{4}-/d{4}-/d{4}-/d{4}$/ 就代表正确的信用卡格式。
下一个例子,则是用正规表示法来验证使用者的英文名字,例如:
你的英文全名:(格式:First Last 或 First Middle Last) 当 onBlur 发生时,换句话说,JavaScript 会呼叫函数 checkEnglishName( ) 来对填入的资料进行验证。相关原始码如下:
<SCRIPT>
function checkEnglishName(control)
{
var re1 = /^[A-Za-z/-]+/s+[A-Za-z/-]+$/;
var re2 = /^[A-Za-z/-]+/s+[A-Za-z/-]+/s+[A-Za-z/-]+$/;
if (!re1.test(control.value) && !re2.test(control.value))
alert("你的英文名字格式不对!");
}
</SCRIPT>
<FORM>你的英文全名:<INPUT οnblur=checkEnglishName(this)>(格式:First Last 或 First Middle Last) </FORM>
正规式对象的方法可列表如下:
正规式对象的方法 功能 re.compile(pattern, flag) 对正规式对象 re 进行编译,以增加比对速度 re.exec(string) 或 re(string) 比对正规式,并传回数组 re.test(string) 比对正规式,并传回比对结果(成功或失败)
在上述范例中,我们只用到了正规式对象的 test() 方法来判断比对是否成功,其它方法会在后序章节提到。
在进行窗体资料验证之前,我们应先进行窗体资料修改,例如拿掉不必要的空格、英文字母大小写转换等,这些工作也可以由字符串的 replace() 方法或正规式的 exec() 方法来达成,这是我们下一节的主题。
在下列的表格中,我们使用几个简单的范例来对正规式的应用做较完整的说明:
正规式 说明及范例 比对不成立之字符串
/a/ 含字母 "a" 的字符串,例如:"ab", "bac", "cba" "xyz" /a./ 含字母 "a" 以及其后任一个字符的字符串,例如:"ab", "bac" "a", "ba"
/^xy/ 以 "xy" 开始的字符串,例如:"xyz", "xyab" "axy", "bxy"
/xy$/ 以 "xy" 结尾的字符串,例如:"axy", "abxy" "xya", "xyb"
[13579] 包含 "1" 或 "3" 或 "5" 或 "7" 或 "9" 的字符串,例如:"a3b", "1xy" "y2k" [0-9] 含数字之字符串 不含数字之字符串
[a-z0-9] 含数字或小写字母之字符串 不含数字及小写字母之字符串
[a-zA-Z0-9] 含数字或字母之字符串 不含数字及字母之字符串
b[aeiou]t "bat", "bet", "bit", "bot", "but" "bxt", "bzt"
[^0-9] 不含数字之字符串 含数字之字符串
[^aeiouAEIOU] 不含元音之字符串 含元音之字符串
[^/^] 不含 "^" 之字符串,例如:"xyz", "abc" "xy^", "a^bc"
请注意在上表中,"^" 在两条斜线中,代表一个字符串的开始位置,因此 /^xy/ 代表以 "xy" 开始的字符串。同理,"$" 在两条斜线中,代表一个字符串的结束位置,因此 /xy$/ 代表以 "xy" 结束的字符串。但是如果将 "^" 放在两个方括号中,就代表「否定」,因此 [^aeiouAEIOU] 代表不含元音之字符串。
有些正规式会常被用到,因此已被定义为特定字符,这些字符可列表说明如下:
正规表示法的特定字符 说明 等效的正规表示法 /d 数字 [0-9]
/D 非数字 [^0-9]
/w 数字、字母、底线 [a-zA-Z0-9_]
/W 非 /w [^a-zA-Z0-9_]
/s 空格符 [/r/t/n/f]
/S 非空格符 [^/r/t/n/f]
此外,我们可定义字符的重复次数,如下:
正规表示法 说明 /a?/ 有或无 a
/a+/ 一或多个 a
/a*/ 零或多个(即任意个) a
/a{4}/ 四个 a
/a{5,10}/ 五至十个 a
/a{5,}/ 至少五个 a
/a{,3} 至多三个 a
/a.{5}b/ a 和 b中间夹五个(非换行)字符