JavaScript 如何使用正則表示式
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
舉例來說,我們的身份證字號的格式是由一個大寫英文字母加上九個數字組合而成,我們利用 onBlur 事件來進行正規式的比對,換句話說,當使用者填完資料,要離開此欄位的時候,JavaScript 即會測知 onBlur 事件,並呼叫函式 checkID() 來對填入的資料進行驗證。相關原始碼如下:
<SCRIPT>
function checkID(formElement)
{
var re = /^[A-Z]/d{9}$/;
if (!re.test(formElement.value))
alert("你的身份證號碼格式不對!");
}
</SCRIPT>
<FORM>身份證字號:<INPUT onblur=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 onblur=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 onblur=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中間夾五個(非換行)字元