⑥ 選擇、分組和引用
Regex的文法還包括指定選擇項、對子運算式分組和引用前一子運算式的特殊字元。字元"|"用於分隔供選擇的字元。例如,/ ab|cd|ef /匹配的是字串“ab”,或者是字串“cd”,又或者是字串“ef”。/ \d{3}|[a-z]{4} /匹配的是三位元字或四個小寫字母。
注意,選擇項是從左至右考慮的,直到發現了匹配項。如果左邊的選擇項匹配,就忽略右邊的匹配項,即使它產生更好的匹配。因此把模式/ a|ab /應用到字串"ab"上時,它只匹配第一個字元。
在Regex中括弧具有幾種作用。
⑴ 把單獨的公事包成子運算式,以便可以像處理一個獨立的單元那樣用|,*,+或?等來處理它們。例如/ java(script)? /匹配的是字串“java”,其後既可以有“script”,也可以沒有。/ (ab|cd)+|ef /匹配的既可以是字串“ef”,也可以是字串“ab”或者“cd”的一次或多次重複。
⑵ 在完整的模式中定義子模式。當一個Regex成功地和目標字串相匹配時,可以從目標串中抽出和括弧中的子模式相匹配的部分。例如假定我們正在檢索的模式是一個或多個小寫字母后面跟隨了一位或多位元字,則可以使用模式/ [a-z]+\d+ /。但是假定我們真正關心的是每個匹配尾部的數字,那麼如果將模式的數字部分放在括弧中(/ [a-z]+(\d+)/ ),就可以從所檢索到的任何匹配中抽取數字了,之後我們會對此進行解釋。
⑶ 括弧允許我們在同一Regex的後部引用前面的子運算式,這是通過在字元"\"後加一位或多位元字實現的,數字指定了帶括弧的子運算式在Regex中的位置。例如,\1引用的是第一個帶括弧的子運算式,\3引用的是第三個帶括弧的子運算式。注意由於子運算式可以被嵌套在別的子運算式中,所以它的位置是被計數的左括弧的位置。例如在下面的Regex中,嵌套的子運算式([Ss]cript)就被指定為\2。
/ ([Jj]ava([Ss]cript)?)\sis\s(fun\w*) /
對Regex中前一子運算式的引用所指的並不是那個子運算式的模式,而是與那個模式相匹配的文本。這樣,引用可以用於實施一條約束,即一個字串各個單獨的部分包含的是完全相同的字元。例如下面的Regex匹配的就是位於單引號或雙引號之內的0個或多個字元。但是,它並不要求開始和結束的引號匹配(例如兩個都是雙引號或者兩個都是單引號):
/[' "][^ ' "]*[' "]/
如果要求開始和結束的引號相匹配,可以使用如下的引用:
/([' "])[^ ' "]*\1/
\1匹配的是第一個帶括弧的字運算式所匹配的模式的文本。在這個例子中,它實施了一條約束,那就是開始的引號必須和結束的引號相匹配。Regex不允許用雙引號括起的字串中有單引號,反之亦然。在字元類中使用引用是不合法的,所以我們不能編寫:
/([' "])[^ \1]*\1/
在後續文章中,我們會看到一種對帶括弧的子運算式的引用,它們是對Regex進行檢索和替換操作的強大特性之一。
在JavaScript 1.5中,無需建立帶編碼的引用就可以將Regex中的項目進行組合。它不是以“(”和“)”對項目進行分組,而以“(?:”和“)”來分組。考慮如下的模式:
/([Jj]ava(?:[Ss]cript)?)\sis\s(fun\w*)/
這裡子運算式(?:[Ss]cript)僅僅用於分組,因此複製符號“?”可以應用到各個分組。這種改進了的括弧並不產生引用,所以在這個Regex中,\2引用了與(fun\w*)匹配的文本。下表總結了Regex的選擇、分組和引用運算子:
Regex的選擇、分組和引用字元
字元 |
含義 |
| |
選擇。匹配的是該符號左邊的子運算式或右邊的子運算式 |
(...) |
組合。將幾個公事包為一個單元,這個單元可由*、+、?和|等符號使用,而且還可以記住和這個組合匹配的字元以供此後的引用使用。 |
(?:...) |
只組合。把公事包到一個單元,但是不記憶與該組匹配的字元。 |
\n |
和第n個分組第一次匹配的字元相匹配。組是括弧中的子運算式。組號是從左至右計數的左括弧數,以(?:形式分組的組不編碼。 |