| PostgreSQL 7.4 文檔 | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Chapter 9. 函數和操作符 | Fast Forward | Next |
PostgreSQL 提供了三種實現模式匹配 的方法:SQL LIKE 操作符,更近一些的 SQL99 SIMILAR TO 操作符, 和POSIX-風格正則表達式. 另外還有一個模式匹配函數 substring 可以用, 可以使用 SQL99 風格的或者 POSIX 風格的正則表達式。
提示: 如果你的模式匹配的要求比這些還多,或者想寫一些模式驅動的 替換和轉換,請考慮用 Perl 或 Tcl 寫一個用戶定義函數.
string LIKE pattern [ ESCAPE escape-character ] string NOT LIKE pattern [ ESCAPE escape-character ]
每個 pattern 定義一個字串的集合. 如果該 string 包含在 pattern 代表的字串集合裡,那麼 LIKE 表達式返回真. (和我們想象的一樣,如果 LIKE 返回真,那麼 NOT LIKE 表達式返回假, 反之亦然。一個等效的表達式是 NOT (string LIKE pattern).)
如果 pattern 不包含百分號 或者下劃線,那麼該模式只代表它本身; 這時候 LIKE 的行為就象等號操作符. 在 pattern 裡的下劃線 (_)代表(匹配)任何單個字符; 而一個百分號(%)匹配任何零或更多 字符長的字串.
下面是一些例子︰
'abc' LIKE 'abc' true 'abc' LIKE 'a%' true 'abc' LIKE '_b_' true 'abc' LIKE 'c' false
LIKE 模式匹配總是覆蓋整個字串. 要匹配在字串內部任何位置的模式,該模式必須以百分號開頭和結尾.
要匹配文本的下劃線或者百分號,而不是匹配其它字符, 在pattern 裡相應的字符必須 前導逃逸字符.缺省的逃逸字符是反斜扛,但是你可以用 ESCAPE 子句指定一個. 要匹配逃逸字符本身,寫兩個逃逸字符.
請注意反斜扛在字串文本裡已經有特殊含義了,所以如果你寫一個 包含反斜扛的模式常量,那你就要在 SQL 語句裡寫兩個反斜扛. 因此,寫一個匹配單個反斜扛的模式實際上要在語句裡寫四個反斜扛. 你可以通過用 ESCAPE 選擇一個不同的逃逸字符 來避免這樣;這樣反斜扛就不再是 LIKE 的特殊字符了. 但仍然是字符文本分析器的特殊字符,所以你還是需要兩個反斜扛.)
我們也可以通過寫成 ESCAPE '' 的方式 有效地關閉逃逸機制,這時,我們就不能關閉下劃線和百分號的特殊含義.
關鍵字 ILIKE 可以用于替換 LIKE, 令該匹配就當前的區域設置是大小寫無關的. 這個特性不是 SQL 標準,是 PostgreSQL 擴展.
操作符 ~~ 等效于 LIKE, 而 ~~* 對應 ILIKE. 還有 !~~ 和 !~~* 操作符 分別代表 NOT LIKE 和 NOT ILIKE.所有這些操作符都是 PostgreSQL 特有的.
string SIMILAR TO pattern [ESCAPE escape-character] string NOT SIMILAR TO pattern [ESCAPE escape-character]
SIMILAR TO 根據自己的模式是否匹配給定字串而 返回真或者假。它和 LIKE 非常類似,只不過它 使用 SQL99 定義的正則表達式理解模式。 SQL99 的正則表達式是在 LIKE 表示法和普通的正則表達式表示法之間古怪的交叉。
類似 LIKE,SIMILAR TO 操作符只有在它的模式匹配整個字串的時候才能成功;這一點和普通的 正則表達式的習慣不同,在普通的正則表達式裡,模式匹配字串的任意 部分。 和 LIKE 類似的地方還有,SIMILAR TO 使用 _ 和 % 作為分別代表任意字串和任意字串字符 的通配符。(這些和 POSIX 正則表達式裡的 . 和 .* 兼容)
除了這些從 LIKE 借用的功能之外, SIMILAR TO 支持下面這些從 POSIX 正則表達式借用的 模式匹配元字符:
| 標識選擇(兩個候選之一)。
* 表示重復前面的項零次或更多次。
+ 表示重復前面的項一次或更多次。
可以使用圓括弧 () 把項組合成一個邏輯項。
一個方括弧表達式 [...] 聲明一個字符表, 就像 POSIX 正則表達式一樣。
請注意沒有提供範圍重復(? 和 {...}), 盡管它們在 POSIX 裡有。同時,點(.)不是元字符。
和 LIKE 一樣,反斜槓關閉所有這些元字符的特殊含義; 當然我們也可以用 ESCAPE 聲明另外一個逃逸字符。
一些例子:
'abc' SIMILAR TO 'abc' true 'abc' SIMILAR TO 'a' false 'abc' SIMILAR TO '%(b|d)%' true 'abc' SIMILAR TO '(b|c)%' false
帶三個參數的substring, substring(string from pattern for escape-character), 提供了一個從字串中抽取一個匹配SQL99正則表達式模式的子字串的函數。 和SIMILAR TO一樣,聲明的模式必須匹配整個數據串,否則函數失效並 返回 NULL。為了標識在成功的時候應該返回的模式部分,模式 必須出現後跟雙引號(")的兩個逃逸字符。匹配這兩個標記 之間的模式的字串將被返回。
一些例子:
substring('foobar' from '%#"o_b#"%' FOR '#') oob
substring('foobar' from '#"o_b#"%' FOR '#') NULL
Table 9-11 列出了所有可用的 用于 POSIX 正則表達式的操作符。
Table 9-11. 正則表達式匹配操作符
| 操作符 | 描述 | 例子 |
|---|---|---|
| ~ | 匹配正則表達式,大小寫相關 | 'thomas' ~ '.*thomas.*' |
| ~* | 匹配正則表達式,大小寫無關 | 'thomas' ~* '.*Thomas.*' |
| !~ | 不匹配正則表達式,大小寫相關 | 'thomas' !~ '.*Thomas.*' |
| !~* | 不匹配正則表達式,大小寫無關 | 'thomas' !~* '.*vadim.*' |
POSIX 正則表達式提供了比 LIKE 和 SIMILAR TO 操作符 更強大的模式匹配的方法.許多 Unix 工具,比如 egrep, sed,或 awk 使用一種與我們這裡描述的類似的模式匹配語言.
正則表達式是一個字符序列,它是定義一個字串集合 (一個正則集合)的縮寫. 如果一個字串是正則表達式描述的正則集合中的一員時, 我們就說這個字串匹配該正則表達式. 和 LIKE 一樣,模式字符準確地匹配字串字符, 除非在正則表達式語言裡有特殊字符 --- 不過正則表達式用的 特殊字符和 LIKE 用的不同. 和 LIKE 不一樣的是,正則表達式 可以匹配字串裡的任何位置,除非該正則表達式明確地掛接在字串 的開頭或者結尾.
一些例子:
'abc' ~ 'abc' true 'abc' ~ '^a' true 'abc' ~ '(b|d)' true 'abc' ~ '^(b|c)' false
帶兩個參數的substring,substring(string from pattern),提供了從字串中抽取一個匹配 POSIX 正則表達式模式的 子字串的方法。如果沒有匹配它返回 NULL,否則就是文本中匹配模式的那部分。 但是如果該模式包含任何圓括弧,那麼將返回匹配第一對子表達式(對應第一個左圓括弧的) 的文本。如果你想在表達式裡使用圓括弧,那麼你總可以在最外圍放上一對兒圓括弧 來避免出現這個問題。又見下面描述的非捕獲性圓括弧。
一些例子:
substring('foobar' from 'o.b') oob
substring('foobar' from 'o(.)b') o
PostgreSQL 的正則表達式是使用 Henry Spencer 寫的一個包來實現的。下面的正則表達式的大部分描述都是從他的手冊頁裡面 逐字拷貝過來的。
正則表達式("RE"),在POSIX1003.2 中定義, 它有兩種形式:擴展的RE或者是ERE (基本上就是那些在 egrep 裡的), "基本"的RE或者是BRE (基本上就是那些在 ed裡的)。 PostgreSQL 兩種形式都實現了,並且還做了一些POSIX裡面沒有的, 但是因為在類似 Perl 或者 Tcl 這樣的語言中得到廣泛應用的一些擴展。 使用了那些非POSIX擴展的 RE 叫高級 RE, 或者我們文檔裡說的 ARE。ARE 幾乎完全是 ERE 的超集,但是 BRE 有幾個符號上的不兼容(以及更多的限制)。我們首先描述 ARE 和 ERE 形式, 描述那些只適用于 ARE 的特性,然後描述 BRE 的區別是什麼。
注意: 我們可以通過設置運行時參數 regex_flavor (在 Section 16.4 裡面描述)來選擇 PostgreSQL 接受的正則表達式的形式。 通常的設置是advanced(高級),但是我們可以選擇 extended 和 7.4 以前的PostgreSQL版本做到最大的向下兼容。
(現代)的 RE 是一個或多個非空的 分支, 由 | 分隔.它匹配任何匹配其中一個分支的東西.
一個分支是一個或多個有修飾的原子或者約束 連接而成.一個原子匹配第一個,然後後面的原子匹配第二個, 以此類推.
一個有修飾的原子是一個原子, 後面可能跟著一個量詞。沒有量詞的時候,它匹配一個原子, 有量詞的時候,它可以匹配若幹個原子。原子可以是在 Table 9-12裡面顯示的任何可能。 可能的量詞和他們的含義在 Table 9-13 裡顯示。
一個 constraint 匹配一個空字串,但只是在滿足特定條件下 才匹配。約束可以在能夠使用原子的地方使用,只是她不能跟著量詞。最簡單 的原子在 Table 9-14 裡顯示; 更多的約束稍後描述。
Table 9-12. 正則表達式原子
| 原子 | 描述 |
|---|---|
| (re) | (這裡的 re 是任何正則表達式) 匹配一個對 re 的匹配,有可報告的匹配信息 |
| (?:re) | 同上,但是匹配不會被報告 (一個"不捕獲"圓括弧) (只在 ARE 中有) |
| . | 匹配任意單個字符 |
| [chars] | 一個 方括弧表達式, 匹配任意的字符(參閱 Section 9.6.3.2 獲取更多細節) |
| \k | (這裡的 k 是非字母數字字符) 匹配一個當作普通字符看待的特定字符, 比如,\\ 匹配一個反斜槓 |
| \c | 這裡的 c 是一個字母數字 (可能跟著其它字符),它是一個逃逸, 參閱 Section 9.6.3.3(僅存在于 ARE; 在 ERE 和 BRE 中,它匹配 c) |
| { | 如果後面跟著一個字符,而不是數字, 那麼就匹配左花括弧{;如果跟著一個數字, 那麼它是範圍的開始(見下面) |
| x | 這裡的 x 是一個沒有其它特征的單個字符, 則匹配該字符 |
RE 不能以 \ 結尾。
注意: 要記住反斜槓(\)在 PostgreSQL 字串文本中已經有特殊含義了。 要寫一個包含反斜槓的模式,你必須在語句裡寫兩個反斜槓。
Table 9-13. 正則表達式量詞
| 量詞 | 匹配 |
|---|---|
| * | 一個匹配 0 或者更多個原子的序列 |
| + | 一個匹配 1 或者更多個原子的序列 |
| ? | 一個匹配 0 個或者 1 個原子的序列 |
| {m} | 一個正好匹配 m 個原子的序列 |
| {m,} | 一個匹配m 個或者更多原子的序列 |
| {m,n} | 一個匹配 m 到 n 個(包含兩端) 原子的序列;m 不能比 n 大 |
| *? | * 的非貪婪模式 |
| +? | + 的非貪婪模式 |
| ?? | ? 的非貪婪模式 |
| {m}? | {m} 的非貪婪模式 |
| {m,}? | {m,} 的非貪婪模式 |
| {m,n}? | {m,n} 的非貪婪模式 |
{...} 的形式被稱作範圍。 一個範圍內的數字 m 和 n 都是無符號十進制整數, 允許的數值從 0 到 255(閉區間)。
非貪婪的量詞(只在 ARE 中可用)匹配對應的正常 (貪婪)模式,區別是它尋找最少的匹配,而不是最多的匹配。 參閱 Section 9.6.3.5 獲取細節。
注意: 一個量詞不能緊跟在另外一個量詞後面。量詞不能是表達式或者子表達式的開頭, 也不能跟在 ^ 或者 | 後面。
Table 9-14. 正則表達式約束
| 約束 | 描述 |
|---|---|
| ^ | 匹配字串的開頭 |
| $ | 匹配字串的結尾 |
| (?=re) | 正前瞻 匹配任何匹配 re 的 子字串起始點(只在 ARE 中有) |
| (?!re) | 負前瞻 匹配任何不匹配 re 的子字串的起始點。(只在 ARE 中有) |
前瞻約束不能包含後引用 (參閱 Section 9.6.3.3),並且在裡面的所有圓括弧 都被認為是不捕獲的。
方括弧表達式是一個包圍在 [] 裡的字符列表.它通常匹配任意單個 列表中的字符(又見下文). 如果列表以 ^ 開頭,它匹配 任意單個(又見下文)不在該列表中的字符. 如果該列表中兩個字符用-隔開, 那它就是那兩個字符(包括在內)之間的所有字符範圍的縮寫, 比如,在 ASCII 裡 [0-9] 包含任何十進制數字. 兩個範圍共享一個終點是非法的,比如, a-c-e.這個範圍與字符集關系密切, 可移植的程序不應該依靠它們.
想在列表中包含文本 ],可以讓它做 列表的首字符(可能會在一個 ^ 後面). 想在列表中包含文本 -,可以讓它做 列表的首字符或者末字符,或者一個範圍的第二個終點. 想在列表中把文本-當做範圍的起點, 把它用 [. 和 .] 包圍起來,這樣它就成為一個集合元素(見下文). 除了這些字符本身,和一些用 [ 的組合(見下段),以及逃逸(只在 ARE 中有效)以外,所有其它特殊字符 在方括弧表達式裡都失去它們的特殊含義. 特別是,在 ERE 和 BRE 規則下 \ 不是特殊的, 但在 ARE 裡,它是特殊的(還是引入一個逃逸)。
在一個方括弧表達式裡,一個集合元素(一個字符,一個當做 一個字符的多字符序列,或者一個表示上面兩種情況的集合序列) 包含在 [. 和 .] 裡面的時候表示該集合元素的字符序列.該序列是該方括弧列表 的一個元素.因此一個包含多字符集合元素的方括弧表達式就 可以匹配多于一個字符,比如,如果集合序列包含一個 ch 集合元素, 那麼 RE [[.ch.]]*c 匹配 chchcc 的頭五個字符. (譯注:其實把 [. 和 .] 括起來的當一個字符看就行了.)
注意: PostgreSQL 目前沒有多字符集合元素。這些信息描述了將來可能有的行為。
在方括弧表達式裡,在[= 和 =] 裡包圍的集合元素是一個等效表, 代表等于這裡所有集合元素的字符序列,包括它本身. (如果沒有其它等效集合元素,那麼就好象封裝元素是 [. 和 .].) 比如,如果 o 和 ^ 是一個等效表的成員,那麼 [[=o=]],[[=^=]],和 [o^] 都是同義的.一個等效表不能是一個範圍的 端點.
在方括弧表達式裡,在 [: 和 :] 裡面封裝的字符表名字代表 屬于該表的所有字符的列表. 標準的字符表名字是:alnum, alpha,blank, cntrl,digit, graph,lower, print,punct, space,upper, xdigit. 它們代表在 ctype 裡定義的字符表. 本地化設置可能會提供其他的表.字符表不能用做一個範圍的端點.
在方括弧表達式裡有兩個特例:方括弧表達式 [[:<:]] 和 [[:>:]] 是約束,分別匹配一個單詞開頭和結束的空串. 單詞定義為一個單詞字符序列,前面和後面都沒有其它單詞字符. 單詞字符是一個字母數字(和 ctype 裡定義的一樣) 或者一個下劃線.這是一個擴展,兼容POSIX1003.2, 但那裡面並沒有說明, 而且在準備移植到其他系統裡去的軟件裡一定要小心使用. 通常下面描述的約束逃逸更好些(他們並非更標準,但是肯定更容易敲入)。
逃逸是以 \ 開頭,後面跟著一個字母數字字符得特殊序列。 逃逸有好幾種變體:字符項,表縮寫,約束逃逸,以及後引用。在 ARE 裡, 如果一個 \ 後面跟著一個字母數字,但是並未組成一個合法的逃逸, 那麼它是非法的。在 ERE 裡則沒有逃逸:在方括弧表達式之外,一個跟著字母數字字符 的 \ 只是表示該字符是一個普通的字符,而在一個方括弧表達式裡, \ 是一個普通的字符。(後者實際上是 ERE 和 ARE 之間的不兼容。)
字符項逃逸用于方便我們聲明RE裡那些不可打印的字符。 它們在 Table 9-15 裡列出。
表縮寫逃逸用來提供一些常用的字符表縮寫。 他們在 Table 9-16 裡顯示。
約束逃逸是一個約束,如果滿足特定的條件, 它匹配該空字串。它們在 Table 9-17 裡顯示。
後引用 (\n)匹配數字 n 指定的前面的圓括弧子表達式匹配的同一個字串 (參閱 Table 9-18)。比如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。RE裡子表達式必須完全在後引用前面。 非捕獲圓括弧並不定義子表達式。
注意: 請注意,如果把模式當作一個 SQL 字串常量輸入,那麼逃逸前導的 \ 需要成倍地寫。
Table 9-15. 正則表達式字符項逃逸
| 逃逸 | 描述 |
|---|---|
| \a | 警笛(鈴聲)字符,和 C 裡一樣 |
| \b | 退格,和 C 裡一樣 |
| \B | \ 的同義詞,用于減少反斜槓加倍的需要 |
| \cX | (這裡 X 是任意字符)字符的 低 5 位和 X 裡的相同,其它位都是 0 |
| \e | 集合序列名字是 ESC 的字符, 如果不是,則是八進制值為 033 的字符 |
| \f | 進紙,和 C 裡一樣 |
| \n | 新行,和 C 裡一樣 |
| \r | 回車,和 C 裡一樣 |
| \t | 水平制表符,和 C 裡一樣 |
| \uwxyz | (這裡的 wxyz 和恰好四位十六進制位) 本機字節序的 Unicode 字符 U+wxyz |
| \Ustuvwxyz | (這裡的 stuvwxyz 是恰好八位十六進制位) 為那種假想中的 Unicode 32 位擴展保留的 |
| \v | 垂直制表符,和 C 裡一樣 |
| \xhhh | (這裡 hhh 是一個十六進制序列) 十六進制值為 0xhhh 的字符 (不管用了幾個十六進制位,都是一個字符) |
| \0 | 值為 0 的字符 |
| \xy | (這裡的 xy 是恰好兩個八進制位, 並且不是一個 後引用)八進制值為 0xy 的字符 |
| \xyz | (這裡的 xyz 是恰好三位八進制位, 並且不是一個 後引用) 八進制值為 0xy的字符 |
十六進制位是 0-9,a-f,和 A-F。八進制位是 0-7。
字符項逃逸總是被當作普通字符。比如,\135 是 ASCII 中的 ], 但 \135 並不終止一個方括弧表達式。
Table 9-16. 正則表達式表縮寫逃逸
| 逃逸 | 描述 |
|---|---|
| \d | [[:digit:]] |
| \s | [[:space:]] |
| \w | [[:alnum:]_] (注意,這裡是包含下劃線的) |
| \D | [^[:digit:]] |
| \S | [^[:space:]] |
| \W | [^[:alnum:]_] (注意這裡是包含下劃線的) |
在方括弧表達式裡,\d,\s, 和 \w 會失去他們的外層方括弧,而 \D,\S, 和 \W 是非法的。(也就是說,比如 [a-c\d] 等效于 [a-c[:digit:]]。同樣 [a-c\D],它原來等效于 [a-c^[:digit:]]的,也是非法的。)
Table 9-17. 正則表達式約束逃逸
| 逃逸 | 描述 |
|---|---|
| \A | 只匹配字串開頭,(參閱 Section 9.6.3.5 獲取它和 ^ 區別的信息) |
| \m | 只匹配一個詞的開頭 |
| \M | 只匹配一個詞的結尾 |
| \y | 只匹配一個詞的開頭或者結尾 |
| \Y | 只匹配那些既不是詞的開頭也不是詞的結尾的點 |
| \Z | 只匹配一個字串的結尾 (參閱 Section 9.6.3.5 獲取它和$區別的信息) |
一個詞的定義是上面 [[:<:]] 和 [[:>:]] 的聲明。在方括弧表達式裡,約束逃逸是非法的。
Table 9-18. 正則表達式後引用
| 逃逸 | 描述 |
|---|---|
| \m | (這裡的 m 是一個非零十進制位) 一個指向第 m 個子表達式的後引用 |
| \mnn | (這裡的 m 是一個非零十進制位,而 nn 是更多的十進制位,並且十進制數值 mnn 不能大于到這個位置為止的閉合捕獲圓括弧的個數) 一個指向第 mnn 個子表達式的後引用 |
注意: 在八進制字符項逃逸和後引用之間有一個歷史繼承的歧義存在,這個歧義是 通過啟發分析解決的,像上面描述地那樣。前導零總是表示這是一個八進制逃逸。 而單個非零數字,如果沒有跟著任何其它數字,那麼總是認為是後引用。 一個多數據位的非零開頭的序列也認為是後引用──只要它在合適的子表達式後面 (也就是說。數值在後引用的合法範圍那),否則就認為是一個八進制。
除了上面描述地主要語法之外,還有幾種特殊形式和雜項語法。
通常,RE 的風味由 regex_flavor 決定。但是,這個環境變量 可以被一個指示器前綴覆蓋。如果任何類型的 RE 以***: 開頭,那麼剩下的 RE 都被當作 ARE。如果任何類型的 RE 以 ***=開頭, 那麼剩下的 RE 被當作一個文本串,所有的字符都被認為是一個普通字符。
一個 ARE 可以以嵌入選項開頭:一個(?xyz) 序列(這裡的 xyz 是一個或多個字母字符)聲明影響剩餘 RE 的選項。 這些選項覆蓋任何前面判斷的選項(包括 RE 風味和大小寫敏感性)。可用的選項字母 在 Table 9-19 顯示。
Table 9-19. ARE 嵌入選項字母
| 選項 | 描述 |
|---|---|
| b | 剩下的 RE 是 BRE |
| c | 大小寫敏感匹配(覆蓋操作符類型) |
| e | 剩下的 RE 是 ERE |
| i | 大小寫不敏感匹配(參閱 Section 9.6.3.5) (覆蓋操作符類型) |
| m | n 的歷史同義詞 |
| n | 新行敏感匹配(參閱 Section 9.6.3.5) |
| p | 部分新行敏感匹配(參閱 Section 9.6.3.5) |
| q | 重置 RE 為一個文本("引起")字串,所有都是普通字符 |
| s | 非新行敏感匹配(缺省) |
| t | 緊語法(缺省,見下文) |
| w | 反轉部分新行敏感("怪異")匹配(參閱 Section 9.6.3.5) |
| x | 擴展的語法(見下文) |
嵌入地選項在終止其序列的 ) 發生作用。他們只在 ARE 的開始處 起作用,稍後在裡面就不能再用了。
除了通常的(緊)RE 語法,(這種情況下所有字符都重要), 還有一種擴展語法,可以通過聲明嵌入的 x 選項獲得。 在擴展語法裡,RE 中的空白字符被忽略,就像那些在 # 和新行之間 的字符一樣。這樣就允許我們給一個復雜的 RE 分段和注釋。不過這個基本規則 上有三種例外:
前置了 \ 的空白字符或者 # 保留
方括弧裡的空白或者 # 保留
在多字符符號裡面,空白和注釋是非法的,就像 ARE (?: 或者 BRE \( 那樣。
擴展語法的空白是空白,水平制表符,新行,和任何屬于 space (空白)字符表的字符。
最後,在 ARE 裡,方括弧表達式外面,序列 (?#ttt) (這裡的 ttt 是任意不包含 ) 的文本)是一個注釋, 完全被忽略。同樣,這樣的東西是不允許出現在多字符符號的字符中間的, 比如 (?:。這樣的注釋是比有用的機制的更久遠的歷史造成的, 他們的用法已經廢棄了;我們應該使用擴展語法代替他。
如果聲明了一個初始化的 ***= 指示器,那麼所有這些元語法 擴展都不能使用,因為這樣表示把用戶輸入當作一個文本字串 而不是 RE 對待。
在 RE 可以匹配給出的字串中多于一個子字串的情況下, RE 匹配字串中最靠前的那個子字串。如果 RE 可以匹配在那個位置開始 的多個子字串,那麼它的選擇取決于它的喜好: 要麼是最長的子字串,要麼是最短的。
大多數原子,以及所有約束,都沒有喜好。一個圓括弧包圍的 RE 和這個 RE 有同樣的喜好(可能是沒有)。一個用量詞 {m} 或者 {m}?量化的原子和原子本身有著同樣的喜好(可能沒有)。 一個用其它普通量詞(包括 {m,n} 裡面 m 等于 n)量化的原子喜好最長的匹配。 一個用其它非貪婪的量詞(包括 {m,n}? 裡面的 m 等于 n)量化的原子喜好最短的匹配。 一個分支的喜好和它裡面的第一個有喜好的量化原子相同。 一個由 | 操作符連接起來得兩個或者多個分支喜好最長的匹配。
由規則強加匹配整個 RE 的約束,子表達式也匹配最長或者最短的字串, 以他們的喜好為基礎,在 RE 裡開始得早得子表達式得優先級高于開始的晚得。 請注意因此外層的子表達式的優先級高于它們的組件的子表達式。
量詞 {1,1} 和 {1,1}? 可以分別用于 在一個子表達式或者整個 RE 上強制最長和最短喜好,
匹配長度是以字符衡量的,而不是集合的元素。一個空字串會被認為比什麼都不匹配長。 比如:bb* 匹配 abbbc 的中間三個字符; (week|wee)(night|knights) 匹配 weeknights 的所有十個字符; 而 (.*).* 匹配 abc的時候,圓括弧包圍的子表達式 匹配所有三個字符;而如果用 (a*)* 匹配 bc,那麼 RE 和圓括弧 子表達式都匹配整個字串。
如果聲明了大小寫無關的匹配,那麼效果就好像把所有字母上的 大小寫區別取消了一樣。如果一個存在大小寫差別的字母以一個 普通字符的形式出現在方括弧表達式外面,那麼它實際上被轉換成 一個包含大小寫的方括弧表達式,也就是說,x 變成 [xX]。 如果它出現在一個方括弧表達式裡面,那麼它的所有大小寫的同族都被加入 方括弧表達式中,也就是說,[x] 變成 [xX], 而 [^x] 變成 [^xX]。
如果聲明了新行敏感匹配,. 和使用^的方括弧表達式 將永遠不會匹配新行字符(這樣,匹配就絕對不會誇新行,除非 RE 明確地安排了 這樣的情況)並且^ 和$ 除了分別匹配 字串開頭和結尾之外,還將分別匹配新行後面和前面 的空字串。但是 ARE 逃逸 \A 和 \Z 仍然只匹配字串的開頭和結尾。
如果聲明了部分新行敏感匹配,那麼它影響 . 和方括弧表達式, 這個時候和新行敏感匹配一樣,但是不影響 ^ 和 $。
如果聲明了反轉新行敏感匹配,那麼它影響 ^ 和 $, 作用和新行敏感匹配裡一樣,但是不影響 . 和方括弧表達式。 這個沒什麼太多用途,只是為了對稱提供的。
在這個實現裡,對 RE 的長度沒有特別的限制,但是,那些希望能夠 有很好移植行的程序應該避免寫超過 256 字節的 RE,因為 POSIX 兼容 的實現可以拒絕接受這樣的 RE。
ARE 實際上和 POSIX ERE 不兼容的唯一的特性是在方括弧表達式裡 \ 並不 失去它特殊的含義。所有其它 ARE 特性都使用在 POSIX ERE 裡面是非法或者是 未定義、未聲明效果的語法;指示器的 *** 就是再 POSIX 的 BRE 和 ERE 之外的語法。
許多 ARE 擴展都是從 Perl 那裡借來的,但是有些我做了修改,清理了 一下,以及一些Perl裡沒有出現的擴展。要注意的不兼容包括 \b, \B,對結尾的新行缺乏特別的處理,對那些新行敏感匹配的附加的 補齊方括弧表達式,在前瞻約束裡對圓括弧和方括弧引用的限制,以及最長/最短 匹配(而不是第一匹配)語義。
PostgreSQL 7.4 之前的版本裡的 ARE 和 ERE 存在兩個非常 顯著的不兼容:
在 ARE 裡,後面跟著一個字母數字的 \ 要麼是一個逃逸,要麼是錯誤, 但是在以前的版本裡,她只是寫那個字母數字的另外一種方法。這個應該不是什麼問題, 因為在以前的版本裡沒有什麼原因讓我們寫這樣的序列。
在 ARE 裡,\在 []裡還是一個特殊字符, 因此在方括弧表達式裡的一個文本 \ 必須寫成 \\。
雖然這些區別對大多數應用都來說都可能不是問題, 但必要時你可以通過設置 regex_flavor 為 extended 來避免這些問題。
BRE 在幾個方面和 ERE 不太一樣。|,+,和 ? 都是普通字符,它們沒有等效的功能替換。範圍的分隔符是 \{ 和 \}, 因為 { 和 } 本身是普通字符。嵌套的子表達式的圓括弧是 \( 和 \),因為 ( 和 ) 自身是普通字符。 除非在 RE 開頭或者是圓括弧封裝的子表達式開頭,^ 都是普通字符, 除非在 RE 結尾或者是圓括弧封裝的子表達式的結尾,$ 是一個普通字符, 而如果 * 出現在 RE 開頭或者是圓括弧封裝的子表達式開頭 (前面可能有 ^ ),那麼它是個普通字符。 最後,可以用單數字的後引用,以及 \< 和 \> 分別是 [[:<:]] 和 [[:>:]]的同義詞;沒有其它的逃逸。