這兩天有點空,但是也不能這么閑着啊。所以就翻了翻 <<精通正則表達式>> 一書。 發現了很多自己不了解的東西(汗顏阿,自己知道的東西太少了!)。其中"|"就是其中一個。不懂就補吧,所以就有了下面的一點記錄。
“| ” 他的意思就是 “或 ” 。 用他我們可以把不同的 子表達式 合成一個總表達式,而這個總的表達式可以匹配 任意一個 的子表達式。我覺得下面有幾個名稱需要解釋一下。
表達式中被 “| ” 分格開的部分。如圖 中的 “Back ” 、 “Go ” 和 “Do ” 就分別是一個子表達式。(這里對子表達方式的定義只是適用於多選結構)
表示該表達式可以匹配上例中的 “Back ” 、 “Go ” 或 “Do ” 中的任何但是 只能是一個 。 也就是說他不能匹配 “BackDo ” 或 “GoDo ” 這樣的字符串。
下面我們就舉幾個例子來說明他的用法。
看看 “Jettery|Jettrey ” 和 “Jett(er|re)y ” 之間有什么區別。他們匹配的結果是否相同? 如果從匹配結果來看的話他們是等價的。都能夠匹配“Jettery”或“Jettrey”。但是過程確實不一樣的。在 “Jettery|Jettrey ” 中我們可以很容易的區分出子表達式分別是 “Jettery ” 和 “Jettrey ” 。但是在 “Jett(er|re)y ” 中就不是這個樣子了。他的子表達式分別是 “er ” 和 “re ” ,為什么他們的子表達式是 “er ” 和 “re ” 而不是 “Jett(er ” 和 “re)y ” 呢?上面不是說子表達式是被 “| ” 分隔開的部分嗎。在這個表達式中 “Jett(er ” 和 “er)y ” 的確是被 “| ” 分隔開的兩個部分啊?。對這個沒有錯,但是因為 “() ” 的存在改變了 “| ” 的作用范圍。那么在這個表達式中 “| ” 的作用范圍就只是 “(erre) ” 了。在這個范圍中就符合我們上面對於子表達式的定義了。我們可以通過下面這兩個圖來證明這一點。

Jettery 和 Jettrey 分別為子表達式

總表達式由三個部分組成:
-
Jett:用於匹配開頭的“Jett”
-
(er|re):這是一個可以被捕獲的子表達式。這個是子表達式就是 “| ” 元字符的操作范圍。 “er ” 和 “re ” 就成被 “| ” 分開的兩個子表達式。就是圖中1所匹配的內容了。
-
y : 匹配最后的y。
![]() |
“(...) ”元字符可以改變“| ”元字符的作用范圍。 |
這兩個表達式一樣嗎?如果不一樣,他們的區別在什么地方呢?事實上這兩個表達式有着很大的差別。這一點從匹配的結果就可以看出來。 例如第一個表達式能夠匹配“Data: Mon ,23 Oct ”,但是卻不能匹配“From: JetGeng@hotmail.com ”。 但是第二個卻可以。問題處在那里呢。還是“(...) ”改變了"|"的作用范圍。
在正則表達式中使用“| ”元字符的時候一點先要確定“| ”的作用范圍, 根據這個作用范圍判斷出被分成的子表達式。這樣就可以確保“| ”能夠返回給你你需要的東西。
Note![]() |
如果使用NFA引擎類型的正則表達式驅動,注意分支不宜太多,否則會引起性能問題。具體的原因可能的話再另外再寫。 |