前面幾節講解了如何在 JavaScript 中使用正規表示式,以及如何執行匹配,本節就來講一下正規表示式的具體語法。
正規表示式是一種通用的工具,在 JavaScript、PHP、Java、Python、C++ 等幾乎所有的程式語言中都能使用;但是,不同程式語言對正規表示式語法的支援不盡相同,有的程式語言支援所有的語法,有的僅支援一個子集。本節講到的正規表示式語法適用於 JavaScript。
正規表示式的語法體現在字元模式上。字元模式是一組特殊格式的字串,它由一系列特殊字元和普通字元構成,其中每個特殊字元都包含一定的語意和功能。
描述字元
根據正規表示式語法規則,大部分字元僅能夠描述自身,這些字元被稱為普通字元,如所有的字母、數位等。
元字元就是擁有特動功能的特殊字元,大部分需要加反斜槓進行標識,以便於普通字元進行區別,而少數元字元,需要加反斜杠,以便轉譯為普通字元使用。JavaScript 正規表示式支援的元字元如表所示。
元字元
元字元 |
描述 |
. |
查詢單個字元,除了換行和行結束符 |
w |
查詢單詞字元 |
W |
查詢非單詞字元 |
d |
查詢數位 |
D |
查詢非數位字元 |
s |
查詢空白字元 |
S |
查詢非空白字元 |
b |
匹配單詞邊界 |
B |
匹配非單詞邊界 |
|
查詢 NUL字元 |
n |
查詢換行符 |
f |
查詢換頁符 |
r |
查詢回車符 |
t |
查詢制表符 |
v |
查詢垂直製表符 |
xxx |
查詢以八進位制數 xxxx 規定的字元 |
xdd |
查詢以十六進位制數 dd 規定的字元 |
uxxxx |
查詢以十六進位制 xxxx規定的 Unicode 字元 |
表示字元的方法有多種,除了可以直接使用字元本身外,還可以使用 ASCII 編碼或者 Unicode 編碼來表示。
範例1
下面使用 ASCII 編碼定義正規表示式直接量。
var r = /x61/;
var s = "JavaScript";
var a = s.match(s);
由於字母 a 的 ASCII 編碼為 97,被轉換為十六進位制數值後為 61,因此如果要匹配字元 a,就應該在前面新增“x”字首,以提示它為 ASCII 編碼。
範例2
除了十六進位制外,還可以直接使用八進位制數值表示字元。
var r = /141/;
var s = "JavaScript";
var a = s.match(r);
使用十六進位制需要新增“x”字首,主要是為了避免語意混淆,而八進位制則不需要新增字首。
範例3
ASCII 編碼只能夠匹配有限的單位元組字元,使用 Unicode 編碼可以表示雙位元組字元。Unicode 編碼方式:“u”字首加上 4 位十六進位制值。
var r = "/u0061/";
var s = "JavaScript";
var a = s.match(s);
在 RegExp() 建構函式中使用元字元時,應使用雙斜槓。
var r = new RegExp("u0061");
RegExp() 建構函式的引數只接受字串,而不是字元模式。在字串中,任何字元加反斜槓還表示字元本身,如字串“u”就被解釋為 u 本身,所以對於“u0061”字串來說,在轉換為字元模式時,就被解釋為“u0061”,而不是“u0061”,此時反斜槓就失去跳脫功能。解決方法:在字元 u 前面加雙反斜槓。
描述字元範圍
在正規表示式語法中,放括號表示字元範圍。在方括號中可以包含多個字元,表示匹配其中任意一個字元。如果多個字元的編碼順序是連續的,可以僅指定開頭和結尾字元,省略中間字元,僅使用連字元
~
表示。如果在方括號內新增脫字元
^
字首,還可以表示範圍之外的字元。例如:
-
[abc]:查詢方括號內任意一個字元。
-
[^abc]:查詢不在方括號內的字元。
-
[0-9]:查詢從 0 至 9 範圍內的數位,即查詢數位。
-
[a-z]:查詢從小寫 a 到小寫 z 範圍內的字元,即查詢小寫字母。
-
[A-Z]:查詢從大寫 A 到大寫 Z 範圍內的字元,即查詢大寫字母。
-
[A-z]:查詢從大寫 A 到小寫 z 範圍內的字元,即所有大小寫的字母。
範例1
字元範圍遵循字元編碼的順序進行匹配。如果將要匹配的字元恰好在字元編碼表中特定區域內,就可以使用這種方式表示。
如果匹配任意 ASCII 字元:
var r = /[u0000-u00ff]/g;
如果匹配任意雙位元組的漢字:
var r = /[^u0000-u00ff]/g;
如果匹配任意大小寫字母和數位:
var r = /[a-zA-Z0-9]/g;
使用 Unicode 編碼設計,匹配數位:
var r = /[u0030-u0039]/g;
使用下面字元模式可以匹配任意大寫字母:
var r = /[u0041-u004A]/g;
使用下面字元模式可以匹配任意小寫字母:
var r = /[u0061-u007A]/g;
範例2
在字元範圍內可以混用各種字元模式。
var s = "abcdez"; //字串直接量
var r = /[abce-z]/g; //字元a、b、c,以及從e~z之間的任意字元
var a = s.match(r); //返回陣列["a","b","c","e","z"]
範例3
在中括號內不要有空格,否則會誤解為還要匹配空格。
var r = /[0-9]/g;
範例4
字元範圍可以組合使用,以便設計更靈活的匹配模式。
var s = "abc4 abd6 abe3 abf1 abg7"; //字串直接量
var r = /ab[c-g][1-7]/g; //前兩個字元為ab,第三個字元為從c到g,第四個字元為1~7的任意數位
var a = s.match(r); //返回陣列["abc4","abd6","abe3","abf1","abg7"]
範例5
使用反義字元範圍可以匹配很多無法直接描述的字元,達到以少應多的目的。
var r = /[^0123456789]/g;
在這個正規表示式中,將會匹配除了數位以外任意的字元。反義字元類比簡單字元類的功能更強大和實用。
選擇匹配
選擇匹配類似於 JavaScript 的邏輯與運算,使用豎線
|
描述,表示在兩個子模式的匹配結果中任選一個。例如:
1) 匹配任意數位或字母
var r = /w+|d+/;
2) 可以定義多重選擇模式。設計方法:在多個子模式之間加入選擇操作符。
var r = /(abc)|(efg)|(123)|(456)/;
為了避免歧義,應該為選擇操作的多個子模式加上小括號。
範例
設計對提交的表單字串進行敏感詞過濾。先設計一個敏感詞列表,然後使用豎線把它們連線在一起,定義選擇匹配模式,最後使用字串的 replace() 方法把所有敏感字元替換為可以顯示的編碼格式。程式碼如下:
var s = '<meta charset="utf-8">'; //待過濾的表單提交資訊
var r = /'|"|<|>/gi; //過濾敏感字元的正規表示式
function f() { //替換函數
////把敏感字元替換為對應的網頁顯示的編碼格式
return "&#" + arguments[0].charCodeAt(0) + ";";
}
var a =s.replace(r,f); //執行過濾替換
document.write(a); //在網頁中顯示正常的字元資訊
console.log(a);
顯示結果如下: