支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

9.7. 模式比對 #

PostgreSQL 提供了三種不同的模式比對方法:傳統的SQL LIKE 運算子、較新的 SIMILAR TO 運算子(在 SQL:1999 中新增)和POSIX-style 正規表示式。除了基本的這個字串是否符合這個模式?運算子之外,還提供可用於提取或取代符合的子字串,以及在符合的位置分割字串的函數。

提示

如果您有超出此範圍的模式比對需求,請考慮使用 Perl 或 Tcl 編寫使用者定義的函數。

警告

雖然大多數正規表示式搜尋可以非常快速地執行,但可以設計正規表示式來花費任意數量的時間和記憶體來處理。請謹慎接受來自惡意來源的正規表示式搜尋模式。如果您必須這樣做,建議設定語句逾時。

使用 SIMILAR TO 模式的搜尋具有相同的安全風險,因為 SIMILAR TO 提供了與POSIX-style 正規表示式相同的許多功能。

LIKE 搜尋比其他兩個選項簡單得多,因此可以更安全地用於可能帶有敵意的模式來源。

所有三種類型的模式比對運算子都不支援非決定性的定序。如果需要,請將不同的定序套用到運算式以解決此限制。

9.7.1. LIKE #

string LIKE pattern [ESCAPE escape-character]
string NOT LIKE pattern [ESCAPE escape-character]

如果 string 符合提供的 patternLIKE 運算式會傳回 true。(如預期,如果 LIKE 傳回 true,則 NOT LIKE 運算式會傳回 false,反之亦然。等效的運算式為 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 子句選擇不同的逸出字元。 若要比對逸出字元本身,請寫入兩個逸出字元。

注意

如果您關閉了standard_conforming_strings,則您在文字字串常數中寫入的任何反斜線都需要加倍。 有關更多資訊,請參閱第 4.1.2.1 節

也可以透過寫入 ESCAPE '' 來選擇沒有逸出字元。 這有效地停用了逸出機制,這使得無法關閉模式中底線和百分比符號的特殊含義。

根據 SQL 標準,省略 ESCAPE 表示沒有逸出字元(而不是預設為反斜線),並且不允許零長度的 ESCAPE 值。 因此,PostgreSQL 在這方面的行為略有不標準。

可以使用關鍵字 ILIKE 來代替 LIKE,以根據有效的地區設定使比對不區分大小寫。 這不在SQL標準中,但它是 PostgreSQL 擴充功能。

運算子 ~~ 等效於 LIKE~~* 對應於 ILIKE。 還有代表 NOT LIKENOT ILIKE!~~!~~* 運算子。 所有這些運算子都是 PostgreSQL 特有的。 您可能會在 EXPLAIN 輸出和類似位置中看到這些運算子名稱,因為剖析器實際上會將 LIKE 等轉換為這些運算子。

片語 LIKEILIKENOT LIKENOT ILIKE 通常在 PostgreSQL 語法中被視為運算子;例如,它們可以用於 expression operator ANY (subquery) 結構中,儘管不能在此處包含 ESCAPE 子句。在某些不明顯的情況下,可能需要改用底層的運算子名稱。

另請參閱 starts-with 運算子 ^@ 和對應的 starts_with() 函式,它們在只需要匹配字串開頭的情況下非常有用。

9.7.2. SIMILAR TO 正規表示式 #

string SIMILAR TO pattern [ESCAPE escape-character]
string NOT SIMILAR TO pattern [ESCAPE escape-character]

SIMILAR TO 運算子會根據其模式是否與給定的字串匹配,傳回 true 或 false。它與 LIKE 相似,但它使用 SQL 標準對正規表示式的定義來解譯模式。SQL 正規表示式是 LIKE 符號和常見 (POSIX) 正規表示式符號之間的一種奇特組合。

LIKE 一樣,只有在其模式與整個字串匹配時,SIMILAR TO 運算子才會成功;這與常見的正規表示式行為不同,在常見的正規表示式行為中,模式可以匹配字串的任何部分。同樣與 LIKE 一樣,SIMILAR TO 使用 _% 作為萬用字元,分別表示任何單個字元和任何字串(這些相當於 POSIX 正規表示式中的 ..*)。

除了從 LIKE 借用的這些功能之外,SIMILAR TO 還支援從 POSIX 正規表示式借用的這些模式匹配元字元:

  • | 表示交替(兩個選項之一)。

  • * 表示前一個項目重複零次或多次。

  • + 表示前一個項目重複一次或多次。

  • ? 表示前一個項目重複零次或一次。

  • {m} 表示前一個項目精確重複 m 次。

  • {m,} 表示前一個項目重複 m 次或多次。

  • {m,n} 表示前一個項目重複至少 m 次,但不超過 n 次。

  • 括號 () 可用於將項目分組為單個邏輯項目。

  • 方括號表示式 [...] 指定一個字元類別,就像在 POSIX 正規表示式中一樣。

請注意,句點 (.) 不是 SIMILAR TO 的元字元。

LIKE 一樣,反斜線會停用任何這些元字元的特殊含義。可以使用 ESCAPE 指定不同的跳脫字元,或者可以透過寫入 ESCAPE '' 來停用跳脫功能。

根據 SQL 標準,省略 ESCAPE 表示沒有逸出字元(而不是預設為反斜線),並且不允許零長度的 ESCAPE 值。 因此,PostgreSQL 在這方面的行為略有不標準。

另一個非標準擴充是,在跳脫字元後接一個字母或數字可以存取為 POSIX 正規表示式定義的跳脫序列;請參閱下方的表 9.20表 9.21表 9.22

一些範例

'abc' SIMILAR TO 'abc'          true
'abc' SIMILAR TO 'a'            false
'abc' SIMILAR TO '%(b|d)%'      true
'abc' SIMILAR TO '(b|c)%'       false
'-abc-' SIMILAR TO '%\mabc\M%'  true
'xabcy' SIMILAR TO '%\mabc\M%'  false

帶有三個參數的 substring 函式提供了提取符合 SQL 正規表示式模式的子字串。可以根據標準 SQL 語法編寫此函式

substring(string similar pattern escape escape-character)

或使用現在已過時的 SQL:1999 語法

substring(string from pattern for escape-character)

或作為一個普通的 3 參數函式

substring(string, pattern, escape-character)

SIMILAR TO 一樣,指定的模式必須與整個資料字串匹配,否則函式將失敗並傳回 null。為了指示要匹配的資料子字串的模式部分,模式應包含兩個跳脫字元,後跟雙引號 (")。成功匹配時,將傳回與這些分隔符號之間的模式部分匹配的文字。

跳脫雙引號分隔符號實際上將 substring 的模式分成三個獨立的正規表示式;例如,任何一個區段中的垂直線 (|) 僅影響該區段。此外,當資料字串的多少與哪個模式匹配存在任何不明確之處時,這些正規表示式的第一個和第三個被定義為匹配可能的最小文字量,而不是最大文字量。(用 POSIX 的說法,強制第一個和第三個正規表示式為非貪婪的。)

作為 SQL 標準的擴充,PostgreSQL 允許只有一個跳脫雙引號分隔符號,在這種情況下,第三個正規表示式被視為空;或者沒有分隔符號,在這種情況下,第一個和第三個正規表示式被視為空。

以下是一些範例,其中 #" 分隔傳回的字串

substring('foobar' similar '%#"o_b#"%' escape '#')   oob
substring('foobar' similar '#"o_b#"%' escape '#')    NULL

9.7.3. POSIX正規表示式 #

表 9.16 列出了使用 POSIX 正規表示式進行模式匹配的可用的運算子。

表 9.16. 正規表示式匹配運算子

運算子

描述

範例

text ~ textboolean

字串匹配正規表示式,區分大小寫

'thomas' ~ 't.*ma't

text ~* textboolean

字串匹配正規表示式,不區分大小寫

'thomas' ~* 'T.*ma't

text !~ textboolean

字串不匹配正規表示式,區分大小寫

'thomas' !~ 't.*max't

text !~* textboolean

字串不匹配正規表示式,不區分大小寫

'thomas' !~* 'T.*ma'f


POSIX正規表示式提供了比 LIKESIMILAR TO 運算子更強大的模式匹配方法。許多 Unix 工具,例如 egrepsedawk 使用一種與此處描述的語言相似的模式匹配語言。

正規表示式是一個字元序列,它是字串集合(一個正規集合)的簡略定義。如果一個字串是正規表示式所描述的正規集合的成員,則稱該字串與該正規表示式匹配。與 LIKE 一樣,模式字元與字串字元完全匹配,除非它們是正規表示式語言中的特殊字元 — 但正規表示式使用的特殊字元與 LIKE 不同。與 LIKE 模式不同,除非正規表示式明確錨定到字串的開頭或結尾,否則正規表示式允許在字串內的任何位置匹配。

一些範例

'abcd' ~ 'bc'     true
'abcd' ~ 'a.c'    true — dot matches any character
'abcd' ~ 'a.*d'   true — * repeats the preceding pattern item
'abcd' ~ '(b|x)'  true — | means OR, parentheses group
'abcd' ~ '^a'     true — ^ anchors to start of string
'abcd' ~ '^(b|c)' false — would match except for anchoring

POSIX模式語言在下面有更詳細的描述。

帶有兩個參數的 substring 函數,substring(string from pattern),提供了提取與 POSIX 正規表示式模式匹配的子字串的功能。如果沒有匹配項,則返回 null,否則返回與模式匹配的文本的第一部分。但是,如果模式包含任何括號,則返回與第一個帶括號的子表示式(左括號首先出現的那個)匹配的文本部分。如果要在不觸發此異常的情況下在表達式中使用括號,則可以在整個表達式周圍加上括號。如果需要提取的子表達式之前的模式中包含括號,請參閱下面描述的非捕獲括號。

一些範例

substring('foobar' from 'o.b')     oob
substring('foobar' from 'o(.)b')   o

regexp_count 函數計算 POSIX 正規表示式模式與字串匹配的位置數量。它的語法是 regexp_count(string, pattern [, start [, flags ]]). 在 string 中搜尋 pattern,通常從字串的開頭開始,但如果提供了 start 參數,則從該字元索引開始。 flags 參數是一個可選的文本字串,包含零個或多個單字母標誌,用於更改函數的行為。例如,在 flags 中包含 i 指定不區分大小寫的匹配。支援的標誌在表 9.24中描述。

一些範例

regexp_count('ABCABCAXYaxy', 'A.')          3
regexp_count('ABCABCAXYaxy', 'A.', 1, 'i')  4

regexp_instr 函數傳回 POSIX 正規表示式模式與字串匹配的第 N 個匹配項的起始或結束位置,如果沒有此類匹配項,則傳回零。它的語法是 regexp_instr(string, pattern [, start [, N [, endoption [, flags [, subexpr ]]]]]). 在 string 中搜尋 pattern,通常從字串的開頭開始,但如果提供了 start 參數,則從該字元索引開始。如果指定了 N,則找到模式的第 N 個匹配項,否則找到第一個匹配項。如果省略 endoption 參數或指定為零,則該函數傳回匹配項的第一個字元的位置。否則,endoption 必須為 1,並且該函數傳回匹配項之後的字元的位置。 flags 參數是一個可選的文本字串,包含零個或多個單字母標誌,用於更改函數的行為。支援的標誌在表 9.24中描述。對於包含括號的子表示式的模式,subexpr 是一個整數,指示哪個子表示式感興趣:結果識別與該子表示式匹配的子字串的位置。子表示式按其前導括號的順序編號。當省略或為零時,subexpr 的結果識別整個匹配的位置,而不管括號的子表示式如何。

一些範例

regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2)
                                   23
regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2)
                                   6

regexp_like 函數檢查 POSIX 正規表示式模式的匹配是否發生在字串中,傳回布林值 true 或 false。它的語法是 regexp_like(string, pattern [, flags ]). flags 參數是一個可選的文本字串,包含零個或多個單字母標誌,用於更改函數的行為。支援的標誌在表 9.24中描述。如果未指定任何標誌,則此函數具有與 ~ 運算符相同的結果。如果僅指定 i 標誌,則它具有與 ~* 運算符相同的結果。

一些範例

regexp_like('Hello World', 'world')       false
regexp_like('Hello World', 'world', 'i')  true

regexp_match 函數傳回一個文本陣列,其中包含 POSIX 正規表示式模式與字串的第一個匹配項中的匹配子字串。它的語法是 regexp_match(string, pattern [, flags ]). 如果沒有匹配項,則結果為 NULL。如果找到匹配項,並且 pattern 不包含帶括號的子表示式,則結果是一個包含與整個模式匹配的子字串的單個元素文本陣列。如果找到匹配項,並且 pattern 包含帶括號的子表示式,則結果是一個文本陣列,其第 n 個元素是與 pattern 的第 n 個帶括號的子表示式匹配的子字串(不包括非捕獲括號;有關詳細資訊,請參閱下文)。 flags 參數是一個可選的文本字串,包含零個或多個單字母標誌,用於更改函數的行為。支援的標誌在表 9.24中描述。

一些範例

SELECT regexp_match('foobarbequebaz', 'bar.*que');
 regexp_match
--------------
 {barbeque}
(1 row)

SELECT regexp_match('foobarbequebaz', '(bar)(beque)');
 regexp_match
--------------
 {bar,beque}
(1 row)

提示

在您只想獲得整個匹配的子字串,或者在沒有匹配項時獲得 NULL 的常見情況下,最佳解決方案是使用 regexp_substr()。但是,regexp_substr() 僅存在於 PostgreSQL 15 及更高版本中。在舊版本中使用時,您可以提取 regexp_match() 結果的第一個元素,例如

SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1];
 regexp_match
--------------
 barbeque
(1 row)

regexp_matches 函數會傳回一組文字陣列,其中包含 POSIX 正規表示式模式與字串比對中,符合的子字串。它的語法與 regexp_match 相同。如果沒有比對到任何字串,此函數不會傳回任何資料列;如果比對到字串且未指定 g 旗標,則會傳回一個資料列;如果有 N 個比對到的字串且指定了 g 旗標,則會傳回 N 個資料列。每個傳回的資料列都是一個文字陣列,其中包含整個比對到的子字串,或是符合 pattern 的括號子表示式的子字串,如同上述 regexp_match 所述。regexp_matches 接受 表 9.24 中顯示的所有旗標,以及 g 旗標,該旗標會指示它傳回所有比對結果,而不僅僅是第一個。

一些範例

SELECT regexp_matches('foo', 'not there');
 regexp_matches
----------------
(0 rows)

SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g');
 regexp_matches
----------------
 {bar,beque}
 {bazil,barf}
(2 rows)

提示

在大多數情況下,應搭配 g 旗標使用 regexp_matches(),因為如果只想取得第一個比對結果,使用 regexp_match() 會更簡單有效率。然而,regexp_match() 僅存在於 PostgreSQL 10 及更高版本中。在較舊版本中工作時,一個常見的技巧是在子查詢中放置 regexp_matches() 呼叫,例如:

SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab;

如果存在比對結果,則會產生一個文字陣列,如果沒有比對結果,則會產生 NULL,與 regexp_match() 的行為相同。如果沒有子查詢,對於沒有比對結果的資料列,此查詢將不會產生任何輸出,這通常不是所需的行為。

regexp_replace 函數提供以新文字替換符合 POSIX 正規表示式模式的子字串的功能。它的語法為 regexp_replace(source, pattern, replacement [, start [, N ]] [, flags ]). (請注意,除非指定了 start,否則不能指定 N,但可以在任何情況下指定 flags。) 如果 pattern 沒有任何比對結果,則傳回未變更的 source 字串。如果存在比對結果,則傳回 source 字串,並以 replacement 字串替換符合的子字串。replacement 字串可以包含 \n,其中 n 是 1 到 9,表示應該插入符合模式的第 n 個括號子表示式的來源子字串,並且可以包含 \& 以表示應該插入符合整個模式的子字串。如果需要在替換文字中放入一個文字反斜線,請寫入 \\。會在 string 中搜尋 pattern,通常從字串的開頭開始,但如果提供了 start 參數,則從該字元索引開始。預設情況下,只會替換模式的第一個比對結果。如果指定了 N 且大於零,則會替換模式的第 N 個比對結果。如果指定了 g 旗標,或者指定了 N 且為零,則會替換 start 位置或之後的所有比對結果。(當指定 N 時,會忽略 g 旗標。)flags 參數是一個可選的文字字串,包含零個或多個單字母旗標,用於變更函數的行為。支援的旗標(但不包含 g)在 表 9.24 中描述。

一些範例

regexp_replace('foobarbaz', 'b..', 'X')
                                   fooXbaz
regexp_replace('foobarbaz', 'b..', 'X', 'g')
                                   fooXX
regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g')
                                   fooXarYXazY
regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i')
                                   X PXstgrXSQL fXnctXXn
regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i')
                                   A PostgrXSQL function

regexp_split_to_table 函數使用 POSIX 正規表示式模式作為分隔符來分割字串。它的語法為 regexp_split_to_table(string, pattern [, flags ]). 如果 pattern 沒有任何比對結果,則函數會傳回 string。如果至少有一個比對結果,對於每個比對結果,它會傳回從上一個比對結果的結尾(或字串的開頭)到比對結果的開頭的文字。當不再有比對結果時,它會傳回從上一個比對結果的結尾到字串結尾的文字。flags 參數是一個可選的文字字串,包含零個或多個單字母旗標,用於變更函數的行為。regexp_split_to_table 支援 表 9.24 中描述的旗標。

regexp_split_to_array 函數的行為與 regexp_split_to_table 相同,只是 regexp_split_to_array 將其結果作為 text 的陣列傳回。它的語法為 regexp_split_to_array(string, pattern [, flags ]). 參數與 regexp_split_to_table 相同。

一些範例

SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo;
  foo
-------
 the
 quick
 brown
 fox
 jumps
 over
 the
 lazy
 dog
(9 rows)

SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', '\s+');
              regexp_split_to_array
-----------------------------------------------
 {the,quick,brown,fox,jumps,over,the,lazy,dog}
(1 row)

SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
 foo
-----
 t
 h
 e
 q
 u
 i
 c
 k
 b
 r
 o
 w
 n
 f
 o
 x
(16 rows)

正如最後一個範例所示,regexp 分割函數會忽略出現在字串開頭或結尾,或緊接在上一個比對結果之後的零長度比對。這與其他 regexp 函數所實現的 regexp 比對的嚴格定義相反,但在實務上通常是最方便的行為。其他軟體系統(例如 Perl)也使用類似的定義。

regexp_substr 函數會傳回符合 POSIX 正規表示式模式的子字串,如果沒有符合的項目,則傳回 NULL。其語法為 regexp_substr(字串, 模式 [, 開始位置 [, N [, 旗標 [, 子表達式 ]]]])。系統會在 字串 中搜尋 模式,通常從字串的開頭開始,但如果提供 開始位置 參數,則從該字元索引開始。如果指定 N,則傳回模式的第 N 個符合項,否則傳回第一個符合項。旗標 參數是一個可選的文字字串,其中包含零個或多個單字母旗標,用於變更函數的行為。支援的旗標描述於表 9.24。對於包含括號子表達式的模式,子表達式 是一個整數,指示感興趣的子表達式:結果是符合該子表達式的子字串。子表達式按其前導括號的順序編號。當省略或為零時 子表達式,無論括號子表達式如何,結果都是整個匹配項。

一些範例

regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2)
                                    town zip
regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
                                   FGH

9.7.3.1. 正規表示式詳細資訊 #

PostgreSQL 的正規表示式是使用 Henry Spencer 所撰寫的軟體套件來實作。 以下大部分的正規表示式描述都直接複製自他的手冊。

正規表示式 (RE),如POSIX1003.2 中所定義,分為兩種形式:擴充REERE(大致上與 egrep 的形式相同) 和 基本REBRE(大致上與 ed 的形式相同)。PostgreSQL 支援這兩種形式,並且還實作了一些不在 POSIX 標準中,但由於它們在 Perl 和 Tcl 等程式語言中可用而廣泛使用的擴充功能。RE使用這些非 POSIX 擴充功能的RE稱為 進階ARE

注意

PostgreSQL 始終預設正規表示式遵循 ARE 規則。 但是,可以透過在 RE 模式前面加上 嵌入選項來選擇限制性更強的 ERE 或 BRE 規則,如第 9.7.3.4 節所述。 這對於與期望完全POSIX1003.2 規則的應用程式相容性非常有用。

正規表示式定義為一個或多個 分支,以 | 分隔。它匹配任何與其中一個分支匹配的內容。

一個分支是零個或多個 量化原子約束,串連在一起。它匹配第一個匹配項,後跟第二個匹配項,依此類推;一個空分支匹配空字串。

量化原子是一個 原子,可能後跟一個 量詞。如果沒有量詞,它會匹配原子的匹配項。使用量詞時,它可以匹配原子的一些匹配項。原子 可以是 表 9.17 中顯示的任何可能性。可能的量詞及其含義顯示在表 9.18中。

約束 匹配一個空字串,但僅在滿足特定條件時才匹配。約束可以在可以使用原子的地方使用,除了它不能後跟量詞。簡單的約束顯示在表 9.19中;稍後將描述更多約束。

表 9.17. 正規表示式原子

原子 描述
(re) (其中 re 是任何正規表示式) 匹配 re 的匹配項,並記錄該匹配項以供可能的報告
(?:re) 與上述相同,但匹配未記錄以供報告(一組非捕獲括號)(僅限 ARE)
. 匹配任何單個字元
[字元] 一個 括號表達式,匹配任何一個 字元(有關更多詳細資訊,請參閱第 9.7.3.2 節
\k (其中 k 是一個非字母數字字元) 匹配該字元,將其視為普通字元,例如,\\ 匹配一個反斜線字元
\c 其中 c 是字母數字(可能後跟其他字元)是一個 逸脫字元,請參閱第 9.7.3.3 節(僅限 ARE;在 ERE 和 BRE 中,這匹配 c
{ 如果後跟除數字以外的字元,則匹配左大括號字元 {;如果後跟數字,則它是 邊界 的開始(請參閱下文)
x 其中 x 是一個沒有其他意義的單個字元,匹配該字元

RE 不能以反斜線結尾 (\)。

注意

如果您關閉了standard_conforming_strings,則您在文字字串常數中寫入的任何反斜線都需要加倍。 有關更多資訊,請參閱第 4.1.2.1 節

表 9.18. 正規表示式量詞

量詞 匹配
* 原子 0 個或多個匹配項的序列
+ 原子 1 個或多個匹配項的序列
? 原子 0 個或 1 個匹配項的序列
{m} 原子精確 m 個匹配項的序列
{m,} 符合原子 (atom) 的 m 次或更多次的序列
{m,n} 符合原子 (atom) 的 m 次到 n 次(包含)的序列;m 不能超過 n
*? * 的非貪婪版本
+? + 的非貪婪版本
?? ? 的非貪婪版本
{m}? {m} 的非貪婪版本
{m,}? {m,} 的非貪婪版本
{m,n}? {m,n} 的非貪婪版本

使用 {...} 的形式被稱為界限 (bounds)。 界限內的數字 mn 是無符號的十進制整數,允許的值從 0 到 255(包含)。

非貪婪 (Non-greedy) 量詞(僅在 ARE 中可用)匹配與它們對應的普通(貪婪 (greedy))量詞相同的可能性,但優先選擇最小的匹配次數,而不是最大的匹配次數。 詳情請參見第 9.7.3.5 節

注意

一個量詞不能緊接在另一個量詞之後,例如,** 是無效的。 量詞不能開始一個表達式或子表達式,也不能接在 ^| 之後。

表 9.19. 正則表達式約束

約束 (Constraint) 描述
^ 在字串的開頭進行匹配
$ 在字串的結尾進行匹配
(?=re) 正向預查 (positive lookahead) 在任何子字串與 re 開始匹配的位置進行匹配(僅限 ARE)。
(?!re) 負向預查 (negative lookahead) 在任何子字串與 re 無法開始匹配的位置進行匹配(僅限 ARE)。
(?<=re) 正向回顧 (positive lookbehind) 在任何子字串與 re 結束匹配的位置進行匹配(僅限 ARE)。
(?<!re) 負向回顧 (negative lookbehind) 在任何子字串與 re 無法結束匹配的位置進行匹配(僅限 ARE)。

預查和回顧約束不能包含反向引用 (back references)(參見第 9.7.3.3 節),並且其中的所有括號都被視為非捕獲的。

9.7.3.2. 括號表達式 #

括號表達式 (bracket expression) 是用 [] 括起來的字符列表。 它通常匹配列表中的任何單個字符(但請參見下文)。 如果列表以 ^ 開頭,則它匹配在列表其餘部分的任何單個字符。 如果列表中的兩個字符用 - 分隔,則它是該整理序列中這兩個字符之間(包括)的完整字符範圍的簡寫,例如,[0-9]ASCII中匹配任何十進制數字。 兩個範圍共享一個端點是非法的,例如,a-c-e。 範圍非常依賴整理序列,因此可移植程式應避免依賴它們。

要在列表中包含文字 ],請使其成為第一個字符(如果在使用了 ^ 之後)。 要包含文字 -,請使其成為第一個或最後一個字符,或範圍的第二個端點。 要使用文字 - 作為範圍的第一個端點,請將其括在 [..] 中,使其成為整理元素(見下文)。 除了這些字符、一些使用 [ 的組合(見下段)以及轉義符(僅限 ARE)之外,所有其他特殊字符在括號表達式中都失去了它們的特殊意義。 特別是,當遵循 ERE 或 BRE 規則時,\ 並不特殊,但在 ARE 中它是特殊的(作為引入轉義符)。

在括號表達式中,括在 [..] 中的整理元素(一個字符、一個整理得好像它是一個單個字符的多字符序列,或兩者的整理序列名稱)代表該整理元素的字符序列。 該序列被視為括號表達式列表的一個單一元素。 這允許包含多字符整理元素的括號表達式匹配多個字符,例如,如果整理序列包含一個 ch 整理元素,則 RE [[.ch.]]*c 匹配 chchcc 的前五個字符。

注意

PostgreSQL 目前不支持多字符整理元素。 此信息描述了可能的未來行為。

在括號表達式中,括在 [==] 中的整理元素是一個等價類 (equivalence class),代表所有與之等價的整理元素的字符序列,包括它本身。 (如果沒有其他等價的整理元素,則處理方式就像封閉定界符是 [..]。) 例如,如果 o^ 是一個等價類的成員,則 [[=o=]][[=^=]][o^] 都是同義的。 等價類不能是範圍的端點。

在括號表達式中,括在 [::] 中的字符類別的名稱代表屬於該類別的所有字符的列表。 字符類別不能用作範圍的端點。 此POSIX標準定義了以下字元類別名稱:alnum(字母和數字)、alpha(字母)、blank(空格和 Tab)、cntrl(控制字元)、digit(數字)、graph(可列印字元,除了空格)、lower(小寫字母)、print(包含空格的可列印字元)、punct(標點符號)、space(任何空白字元)、upper(大寫字母)和 xdigit(十六進位數字)。對於 7 位 ASCII 字元集中的字元,這些標準字元類別的行為在各個平台上通常是一致的。給定的非 ASCII 字元是否被認為屬於這些類別之一,取決於用於正規表示式函數或運算子的定序 (collation)(請參閱第 23.2 節),或者預設取決於資料庫的 LC_CTYPE 語系設定(請參閱第 23.1 節)。即使在名稱相似的語系中,非 ASCII 字元的分類也可能因平台而異。(但是,C 語系永遠不會將任何非 ASCII 字元視為屬於這些類別中的任何一個。)除了這些標準字元類別之外,PostgreSQL 定義了 word 字元類別,它與 alnum 加上底線字元 (_) 相同,以及 ascii 字元類別,它完全包含 7 位 ASCII 字元集。

括號表達式有兩個特殊情況:括號表達式 [[:<:]][[:>:]] 是約束,分別匹配單字開頭和結尾的空字串。單字定義為既沒有前導也沒有後續單字字元的單字字元序列。單字字元是屬於 word 字元類別的任何字元,也就是任何字母、數字或底線。這是一個擴展,與POSIX1003.2 相容但不符合其規範,在打算移植到其他系統的軟體中應謹慎使用。通常,最好使用下面描述的約束跳脫序列;它們並不更標準,但更容易輸入。

9.7.3.3. 正規表示式跳脫序列 #

跳脫序列 (Escapes) 是以 \ 開頭,後面跟著一個字母數字字元的特殊序列。跳脫序列有多種變體:字元輸入、類別簡寫、約束跳脫序列和反向引用。在 ARE 中,\ 後面跟著一個字母數字字元,但不構成有效的跳脫序列是非法的。在 ERE 中,沒有跳脫序列:在括號表達式之外,\ 後面跟著一個字母數字字元僅表示該字元作為普通字元,而在括號表達式內部,\ 是一個普通字元。(後者是 ERE 和 ARE 之間的一個實際不相容之處。)

字元輸入跳脫序列 (Character-entry escapes) 的存在是為了更容易在 RE 中指定非列印和其他不方便的字元。它們顯示在表格 9.20中。

類別簡寫跳脫序列 (Class-shorthand escapes) 為某些常用的字元類別提供簡寫。它們顯示在表格 9.21中。

約束跳脫序列 (Constraint escape) 是一種約束,如果滿足特定條件,則匹配空字串,並寫成跳脫序列。它們顯示在表格 9.22中。

反向引用 (back reference) (\n) 匹配由數字 n 指定的前一個以括號括起來的子表達式所匹配的相同字串(請參閱表格 9.23)。例如,([bc])\1 匹配 bbcc,但不匹配 bccb。子表達式必須完全位於 RE 中的反向引用之前。子表達式按其前導括號的順序編號。非捕獲括號不定義子表達式。反向引用僅考慮由引用的子表達式匹配的字串字元,而不考慮其中包含的任何約束。例如,(^\d)\1 將匹配 22

表格 9.20. 正規表示式字元輸入跳脫序列

跳脫序列 描述
\a 警報(響鈴)字元,如在 C 中
\b 退格鍵,如在 C 中
\B 反斜線 (\) 的同義詞,有助於減少對反斜線加倍的需求
\cX (其中 X 是任何字元)其低位 5 位與 X 的低位 5 位相同,且其他位全為零的字元
\e 定序序列名稱為 ESC 的字元,如果沒有,則為八進位值為 033 的字元
\f 換頁,如在 C 中
\n 換行符,如在 C 中
\r 歸位字元,如在 C 中
\t 水平 Tab,如在 C 中
\uwxyz (其中 wxyz 正好是四個十六進位數字)其十六進位值為 0xwxyz 的字元
\Ustuvwxyz (其中 stuvwxyz 正好是八個十六進位數字)其十六進位值為 0xstuvwxyz 的字元
\v 垂直 Tab,如在 C 中
\xhhh (其中 hhh 是任何十六進位數字序列)其十六進位值為 0xhhh 的字元(無論使用了多少十六進位數字,都只有一個字元)
\0 其值為 0 的字元(空位元組)
\xy (其中 xy 正好是兩個八進位數字,而不是反向引用)其八進位值為 0xy 的字元
\xyz (其中 xyz 正好是三個八進位數字,而不是反向引用)其八進位值為 0xyz 的字元

十六進位數字是 0-9a-fA-F。八進位數字是 0-7

指定 ASCII 範圍 (0–127) 之外的值的數字字元輸入跳脫序列具有取決於資料庫編碼的含義。當編碼為 UTF-8 時,跳脫序列值等同於 Unicode 代碼點,例如 \u1234 表示字元 U+1234。對於其他多位元組編碼,字元輸入跳脫序列通常只指定字元的位元組值的串連。如果跳脫序列值不對應於資料庫編碼中的任何合法字元,則不會引發錯誤,但它永遠不會匹配任何資料。

字元輸入跳脫序列始終被視為普通字元。例如,\135 在 ASCII 中是 ],但 \135 不會終止括號表達式。

表格 9.21. 正規表示式類別簡寫跳脫序列

跳脫序列 描述
\d 匹配任何數字,如 [[:digit:]]
\s 匹配任何空白字元,如 [[:space:]]
\w 匹配任何單字字元,如 [[:word:]]
\D 匹配任何非數字,如 [^[:digit:]]
\S 匹配任何非空白字元,如 [^[:space:]]
\W 匹配任何非單字字元,如 [^[:word:]]

類別簡寫跳脫字元在方括號表示式中也有效,儘管上面顯示的定義在語法上在該上下文中並不完全有效。例如,[a-c\d] 等同於 [a-c[:digit:]]

表 9.22. 正規表示式約束跳脫字元

跳脫序列 描述
\A 僅在字串的開頭匹配(請參閱第 9.7.3.5 節,了解這與 ^ 有何不同)
\m 僅在單字的開頭匹配
\M 僅在單字的結尾匹配
\y 僅在單字的開頭或結尾匹配
\Y 僅在非單字的開頭或結尾的位置匹配
\Z 僅在字串的結尾匹配(請參閱第 9.7.3.5 節,了解這與 $ 有何不同)

單字的定義與上面的 [[:<:]][[:>:]] 的規範相同。約束跳脫字元在方括號表示式中是非法的。

表 9.23. 正規表示式反向參考

跳脫序列 描述
\m (其中 m 是一個非零數字)對第 m 個子表示式的反向參考
\mnn (其中 m 是一個非零數字,nn 是更多數字,並且十進位值 mnn 不大於到目前為止所看到的右括號的數量)對第 mnn 個子表示式的反向參考

注意

八進位字元輸入跳脫字元和反向參考之間存在固有的模糊性,這可以通過以下啟發法來解決,如上所述。前導零始終表示八進位跳脫字元。單個非零數字(後面沒有其他數字)始終被視為反向參考。如果多位數序列不是以零開頭,並且如果它出現在適當的子表示式之後(即,該數字在反向參考的合法範圍內),則將其視為反向參考,否則將其視為八進位。

9.7.3.4. 正規表示式元語法 #

除了上面描述的主要語法外,還有一些特殊形式和各種可用的語法功能。

RE 可以以兩個特殊的指示符前綴之一開頭。如果 RE 以 ***: 開頭,則 RE 的其餘部分被視為 ARE。(通常這在 PostgreSQL 中沒有任何影響,因為 RE 被假定為 ARE;但如果 ERE 或 BRE 模式已由 regex 函數的 flags 參數指定,則它確實會產生影響。)如果 RE 以 ***= 開頭,則 RE 的其餘部分被視為字串文字,所有字元都被視為普通字元。

ARE 可以以嵌入選項開頭:序列 (?xyz)(其中 xyz 是一個或多個字母字元)指定影響 RE 其餘部分的選項。這些選項會覆蓋任何先前確定的選項 — 特別是,它們可以覆蓋由正規表示式運算子暗示的大小寫敏感行為,或 regex 函數的 flags 參數。可用選項字母顯示在表 9.24中。請注意,這些相同的選項字母也用於 regex 函數的 flags 參數中。

表 9.24. ARE 嵌入選項字母

選項 描述
b RE 的其餘部分是 BRE
c 區分大小寫的匹配(覆蓋運算子類型)
e RE 的其餘部分是 ERE
i 不區分大小寫的匹配(請參閱第 9.7.3.5 節)(覆蓋運算子類型)
m n 的歷史同義詞
n 換行符號敏感匹配(請參閱第 9.7.3.5 節
p 部分換行符號敏感匹配(請參閱第 9.7.3.5 節
q RE 的其餘部分是字串文字(引用),所有普通字元
s 非換行符號敏感匹配(預設)
t 嚴格語法(預設;請參閱下文)
w 反向部分換行符號敏感(怪異)匹配(請參閱第 9.7.3.5 節
x 擴展語法(請參閱下文)

嵌入選項在終止序列的 ) 處生效。它們只能出現在 ARE 的開頭(如果有的話,在 ***: 指示符之後)。

除了通常的(嚴格)RE 語法(其中所有字元都很重要)之外,還有一個擴展語法,可以通過指定嵌入的 x 選項來使用。在擴展語法中,RE 中的空白字元將被忽略,# 和以下換行符號(或 RE 的結尾)之間的所有字元也將被忽略。這允許對複雜的 RE 進行分段和註釋。該基本規則有三個例外

  • 空白字元或前面帶有 \# 會被保留

  • 方括號表示式中的空白或 # 會被保留

  • 空白和註釋不能出現在多字元符號(例如 (?:)中

為此,空白字元是空格、製表符、換行符號以及屬於 space 字元類別的任何字元。

最後,在 ARE 中,在方括號表示式之外,序列 (?#ttt)(其中 ttt 是不包含 ) 的任何文字)是一個註釋,完全被忽略。同樣,這不允許在多字元符號的字元之間,例如 (?:。此類註釋更多的是歷史產物,而不是有用的工具,因此不建議使用;請改用擴展語法。

如果初始 ***= 指示符已指定將用戶的輸入視為字串文字而不是 RE,則沒有這些元語法擴展可用。

9.7.3.5. 正規表示式匹配規則 #

如果 RE 可以匹配給定字串的多個子字串,則 RE 會匹配字串中最早開始的那個。如果 RE 可以匹配從該點開始的多個子字串,則將採用最長可能匹配或最短可能匹配,具體取決於 RE 是貪婪還是非貪婪

RE 是否貪婪取決於以下規則

  • 大多數原子和所有約束都沒有貪婪屬性(因為無論如何它們都無法匹配可變數量的文字)。

  • 在 RE 周圍添加括號不會改變其貪婪性。

  • 具有固定重複量詞({m}{m}?)的量化原子具有與原子本身相同的貪婪性(可能沒有)。

  • 具有其他普通量詞(包括 {m,n},其中 m 等於 n)的量化原子是貪婪的(優先選擇最長匹配)。

  • 帶有非貪婪量詞的量化原子(包括 {m,n}?,且 m 等於 n)是非貪婪的(偏好最短匹配)。

  • 一個分支 (branch) — 也就是說,一個沒有頂層 | 運算子的 RE — 其貪婪性與其中第一個具有貪婪性屬性的量化原子相同。

  • 一個由兩個或多個分支透過 | 運算子連接的 RE 總是貪婪的。

上述規則不僅將貪婪性屬性與個別的量化原子關聯,也與包含量化原子 的分支和整個 RE 關聯。 這意味著匹配的方式是分支或整個 RE 匹配 整體上 最長或最短的子字串。 一旦確定了整個匹配的長度,匹配任何特定子表達式的部分就基於該子表達式的貪婪性屬性來確定,並且 RE 中較早開始的子表達式優先於較晚開始的子表達式。

以下是一些說明範例:

SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})');
Result: 123
SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
Result: 1

在第一種情況下,整個 RE 是貪婪的,因為 Y* 是貪婪的。 它可以從 Y 開始匹配,並且在那裡匹配最長的字串,即 Y123。 輸出是該字串的括號部分,即 123。 在第二種情況下,整個 RE 是非貪婪的,因為 Y*? 是非貪婪的。 它可以從 Y 開始匹配,並且在那裡匹配最短的字串,即 Y1。 子表達式 [0-9]{1,3} 是貪婪的,但它無法更改整體匹配長度的決定; 因此,它被迫只匹配 1

簡而言之,當一個 RE 包含貪婪和非貪婪的子表達式時,總匹配長度將盡可能長或盡可能短,具體取決於分配給整個 RE 的屬性。 分配給子表達式的屬性僅影響允許它們相對於彼此 吃掉 多少匹配。

量詞 {1,1}{1,1}? 可分別用於在子表達式或整個 RE 上強制執行貪婪或非貪婪。 當您需要整個 RE 具有與其元素推導出的貪婪性屬性不同的屬性時,這非常有用。 例如,假設我們試圖將包含一些數字的字串分成數字以及它們之前和之後的部分。 我們可以嘗試這樣做

SELECT regexp_match('abc01234xyz', '(.*)(\d+)(.*)');
Result: {abc0123,4,xyz}

這沒有用:第一個 .* 是貪婪的,所以它會 吃掉 盡可能多的東西,留下 \d+ 在最後一個可能的地方(最後一個數字)進行匹配。 我們可以嘗試通過使其變為非貪婪來解決此問題

SELECT regexp_match('abc01234xyz', '(.*?)(\d+)(.*)');
Result: {abc,0,""}

這也沒有用,因為現在整個 RE 是非貪婪的,因此它會盡快結束整體匹配。 我們可以通過強制整個 RE 變得貪婪來獲得我們想要的東西

SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
Result: {abc,01234,xyz}

將 RE 的整體貪婪性與其組件的貪婪性分開控制,可以在處理變長模式時提供極大的靈活性。

在決定什麼是更長或更短的匹配時,匹配長度以字元為單位測量,而不是以校對元素為單位測量。 空字串被認為比完全沒有匹配更長。 例如:bb* 匹配 abbbc 的中間三個字元; (week|wee)(night|knights) 匹配 weeknights 的所有十個字元; 當 (.*).*abc 匹配時,括號括起來的子表達式匹配所有三個字元; 並且當 (a*)*bc 匹配時,整個 RE 和括號括起來的子表達式都匹配一個空字串。

如果指定了大小寫無關的匹配,其效果就好像字母表中所有大小寫的區別都消失了一樣。 當以多種大小寫形式存在的字母作為普通字元出現在括號表達式之外時,它實際上會轉換為包含兩種大小寫的括號表達式,例如,x 變成 [xX]。 當它出現在括號表達式內時,它的所有大小寫對應項都會添加到括號表達式中,例如,[x] 變成 [xX],而 [^x] 變成 [^xX]

如果指定了換行符敏感匹配,則 . 和使用 ^ 的括號表達式將永遠不會匹配換行符(因此,除非 RE 明確包含換行符,否則匹配不會跨行),並且 ^$ 將分別匹配換行符之後和之前的空字串,此外還分別匹配字串的開頭和結尾。 但是 ARE 跳脫字元 \A\Z 繼續 匹配字串的開頭或結尾。 此外,字元類速記符 \D\W 無論處於何種模式,都將匹配換行符。 (在 PostgreSQL 14 之前,當處於換行符敏感模式時,它們不匹配換行符。 寫入 [^[:digit:]][^[:word:]] 以獲得舊的行為。)

如果指定了部分換行符敏感匹配,這會像換行符敏感匹配一樣影響 . 和括號表達式,但不影響 ^$

如果指定了反向部分換行符敏感匹配,這會像換行符敏感匹配一樣影響 ^$,但不影響 . 和括號表達式。 這不是很有用,但為了對稱性而提供。

9.7.3.6. 限制和相容性 #

在此實作中,未對 RE 的長度施加任何特定限制。 但是,打算高度可移植的程式不應使用長度超過 256 位元組的 RE,因為符合 POSIX 標準的實作可以拒絕接受此類 RE。

ARE 實際上與 POSIX ERE 不相容的唯一特性是 \ 不會失去其在括號表達式內的特殊含義。 所有其他 ARE 特性都使用在 POSIX ERE 中非法或具有未定義或未指定效果的語法; 指示器的 *** 語法同樣超出了 BRE 和 ERE 的 POSIX 語法。

許多 ARE 擴展是從 Perl 借用的,但有些已更改以清理它們,並且缺少一些 Perl 擴展。 值得注意的不相容性包括 \b\B、缺少對尾隨換行符的特殊處理、將補充括號表達式添加到受換行符敏感匹配影響的事物、對前瞻/後顧約束中的括號和反向引用的限制,以及最長/最短匹配(而不是第一次匹配)匹配語意。

9.7.3.7. 基本正規表示式 #

BRE 與 ERE 在幾個方面有所不同。在 BRE 中,|+? 都是普通字元,並且沒有等效的功能。邊界的定界符是 \{\},而 {} 本身則是普通字元。巢狀子運算式的括號是 \(\),而 () 本身則是普通字元。^ 是一個普通字元,除非它位於 RE 的開頭或括號括起來的子運算式的開頭。$ 是一個普通字元,除非它位於 RE 的結尾或括號括起來的子運算式的結尾,而 * 是一個普通字元,如果它出現在 RE 的開頭或括號括起來的子運算式的開頭(在可能的開頭 ^ 之後)。最後,可以使用個位數的反向引用,並且 \<\> 分別是 [[:<:]][[:>:]] 的同義詞;BRE 中沒有其他跳脫字元可用。

9.7.3.8. 與 SQL 標準和 XQuery 的差異 #

自 SQL:2008 以來,SQL 標準包含正則表達式運算符和函數,這些運算符和函數根據 XQuery 正則表達式標準執行模式匹配。

  • LIKE_REGEX

  • OCCURRENCES_REGEX

  • POSITION_REGEX

  • SUBSTRING_REGEX

  • TRANSLATE_REGEX

PostgreSQL 目前尚未實作這些運算符和函數。 在 表 9.25 中顯示,您可以得到每個案例中大致等效的功能。(此表中省略了雙方的各種可選子句。)

表 9.25. 正則表達式函數等效性

SQL 標準 PostgreSQL
string LIKE_REGEX pattern regexp_like(string, pattern)string ~ pattern
OCCURRENCES_REGEX(pattern IN string) regexp_count(string, pattern)
POSITION_REGEX(pattern IN string) regexp_instr(string, pattern)
SUBSTRING_REGEX(pattern IN string) regexp_substr(string, pattern)
TRANSLATE_REGEX(pattern IN string WITH replacement) regexp_replace(string, pattern, replacement)

其他許多 SQL 實作中也提供了類似於 PostgreSQL 提供的正則表達式函數,而 SQL 標準函數則沒有那麼廣泛的實作。 每種實作中正則表達式語法的某些細節可能會有所不同。

SQL 標準運算符和函數使用 XQuery 正則表達式,該正則表達式非常接近上述 ARE 語法。 現有的基於 POSIX 的正則表達式功能和 XQuery 正則表達式之間的顯著差異包括

  • 不支援 XQuery 字元類別減法。此功能的一個範例是使用以下內容來僅匹配英文字母:[a-z-[aeiou]]

  • 不支援 XQuery 字元類別速記 \c\C\i\I

  • 不支援使用 \p{UnicodeProperty} 或反向 \P{UnicodeProperty} 的 XQuery 字元類別元素。

  • POSIX 根據現行語言環境(您可以透過將 COLLATE 子句附加到運算符或函數來控制)來解釋字元類別,例如 \w(請參閱表 9.21)。 XQuery 透過參考 Unicode 字元屬性來指定這些類別,因此只有在使用遵循 Unicode 規則的語言環境時才能獲得等效行為。

  • SQL 標準(而非 XQuery 本身)試圖容納比 POSIX 更多的 換行符號 變體。 上述換行符號敏感匹配選項僅將 ASCII NL (\n) 視為換行符號,但 SQL 會要求我們將 CR (\r)、CRLF (\r\n)(Windows 樣式的換行符號)和一些僅限 Unicode 的字元(如 LINE SEPARATOR (U+2028))也視為換行符號。 值得注意的是,根據 SQL,.\s 應將 \r\n 算作一個字元,而不是兩個字元。

  • 表 9.20 中描述的字元輸入跳脫中,XQuery 僅支援 \n\r\t

  • XQuery 不支援方括號運算式中字元類別的 [:name:] 語法。

  • XQuery 沒有 lookahead 或 lookbehind 約束,也沒有 表 9.22 中描述的任何約束跳脫。

  • 第 9.7.3.4 節中描述的元語法形式在 XQuery 中不存在。

  • XQuery 定義的正則表達式標記字母與 POSIX 的選項字母相關但不相同(表 9.24)。 雖然 iq 選項的行為相同,但其他選項的行為不同。

    • XQuery 的 s (允許點匹配換行符號) 和 m (允許 ^$ 在換行符號處匹配) 標記提供對與 POSIX 的 npw 標記相同的行為的存取權限,但它們匹配 POSIX 的 sm 標記的行為。 請特別注意,點匹配換行符號是 POSIX 中的預設行為,而不是 XQuery 中的預設行為。

    • XQuery 的 x(忽略模式中的空白)標記與 POSIX 的擴展模式標記明顯不同。 POSIX 的 x 標記也允許 # 在模式中開始一個註解,並且 POSIX 不會忽略反斜線後的空白字元。

提交更正

如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用此表單來報告文件問題。