2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 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 搜尋要簡單得多,因此在使用可能來自敵對來源的模式時更安全。

SIMILAR TOPOSIX-style 正則表示式不支援非確定性排序規則。如果需要,請使用 LIKE 或將其他排序規則應用於表示式來繞過此限制。

9.7.1. LIKE #

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

string 匹配所提供的 pattern 時,LIKE 表示式返回 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 模式匹配支援非確定性排序規則(請參閱 第 23.2.2.4 節),例如不區分大小寫的排序規則或忽略標點符號的排序規則。因此,使用不區分大小寫的排序規則,可以實現

'AbC' LIKE 'abc' COLLATE case_insensitive    true
'AbC' LIKE 'a%' COLLATE case_insensitive     true

對於忽略某些字元或總體上認為不同長度的字串相等的排序規則,語義可能會變得稍微複雜一些。請考慮以下示例

'.foo.' LIKE 'foo' COLLATE ign_punct    true
'.foo.' LIKE 'f_o' COLLATE ign_punct    true
'.foo.' LIKE '_oo' COLLATE ign_punct    false

匹配工作方式是將模式劃分為萬用字元序列和非萬用字元字串(萬用字元是 _%)。例如,模式 f_o 被劃分為 f, _, o,模式 _oo 被劃分為 _, oo。當輸入字串可以這樣劃分,使得萬用字元分別匹配一個字元或任意數量的字元,並且非萬用字元部分在適用的排序規則下相等時,輸入字串就匹配該模式。所以例如,'.foo.' LIKE 'f_o' COLLATE ign_punct 為 true,因為 .foo. 可以劃分為 .f, o, o.,然後 '.f' = 'f' COLLATE ign_punct'o' 匹配 _ 萬用字元,並且 'o.' = 'o' COLLATE ign_punct。但是 '.foo.' LIKE '_oo' COLLATE ign_punct 為 false,因為 .foo. 不能以第一字元是任何字元且字串的其餘部分與 oo 相等的方式進行劃分。(請注意,單字元萬用字元始終匹配正好一個字元,與排序規則無關。所以在這個例子中,_ 會匹配 .,但字串的其餘部分將與模式的其餘部分不匹配。)

LIKE 模式匹配總是覆蓋整個字串。因此,如果希望匹配字串中的某個序列,則模式必須以百分號開頭和結尾。

要匹配字面上的下劃線或百分號而不匹配其他字元,pattern 中的相應字元必須在其前面加上跳脫字元。預設的跳脫字元是反斜槓,但可以使用 ESCAPE 子句選擇另一個。要匹配跳脫字元本身,請寫兩個跳脫字元。

注意

如果 standard_conforming_strings 設定為 off,那麼在字面字串常量中寫入的任何反斜槓都需要加倍。有關更多資訊,請參閱 第 4.1.2.1 節

也可以透過寫 ESCAPE '' 來選擇不使用跳脫字元。這實際上停用了轉義機制,從而無法關閉下劃線和百分號在模式中的特殊含義。

根據 SQL 標準,省略 ESCAPE 意味著沒有跳脫字元(而不是預設為反斜槓),並且不允許零長度的 ESCAPE 值。因此,PostgreSQL 在這方面的行為略微不符合標準。

關鍵字 ILIKE 可以替代 LIKE,以根據活動區域設定進行不區分大小寫的匹配。(但這不支援非確定性排序規則。)這不在SQL標準中,而是 PostgreSQL 的擴充套件。

運算子 ~~ 等同於 LIKE,而 ~~* 對應於 ILIKE。還有 !~~!~~* 運算子,分別代表 NOT LIKENOT ILIKE。所有這些運算子都是 PostgreSQL 特有的。你可能會在 EXPLAIN 輸出及類似地方看到這些運算子名稱,因為解析器實際上會將 LIKE 等轉換為這些運算子。

短語 LIKEILIKENOT LIKENOT ILIKEPostgreSQL 語法中通常被視為運算子;例如,它們可以用於 expression operator ANY (subquery) 結構中,儘管那裡不能包含 ESCAPE 子句。在某些晦澀的情況下,可能需要使用底層運算子名稱。

另請參閱開頭匹配運算子 ^@ 和相應的 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)

或者作為普通的三引數函式

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 ]])。patternstring 中搜索,通常從字串開頭開始,但如果提供了 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 ]]]]]).patternstring 中搜索,通常從字串開頭開始,但如果提供了 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(string=>'ABCDEFGHI', pattern=>'(c..)(...)', start=>1, "N"=>1, endoption=>0, flags=>'i', subexpr=>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 個元素是與模式的第 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 行。返回的每一行都是一個文字陣列,包含與整個匹配模式或模式的括號子表示式匹配的子字串,就像上面為 regexp_match 所描述的那樣。regexp_matches 接受 表 9.24 中顯示的所有標誌,再加上 g 標誌,該標誌命令它返回所有匹配項,而不僅僅是第一個。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)

提示

在大多數情況下,regexp_matches() 應與 g 標誌一起使用,因為如果您只想獲取第一個匹配項,使用 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(string, pattern, replacement [, flags ]) 或 regexp_replace(string, pattern, replacement, start [, N [, flags ]]). 如果模式 pattern 沒有匹配,則源字串 string 將原樣返回。如果存在匹配,則返回 string,並將 replacement 字串替換為匹配的子字串。replacement 字串可以包含 \n,其中 n 是 1 到 9,表示應插入與模式的第 n 個括號子表示式匹配的源子字串,並且它可以包含 \& 來表示應插入與整個模式匹配的子字串。如果要將字面反斜槓放入替換文字中,請編寫 \\patternstring 中搜索,通常從字串開頭開始,但如果提供了 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(string=>'A PostgreSQL function', pattern=>'a|e|i|o|u', replacement=>'X', start=>1, "N"=>3, flags=>'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_arraytext 陣列的形式返回其結果。其語法為 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(string, pattern [, start [, N [, flags [, subexpr ]]]]).patternstring 中搜索,通常從字串開頭開始,但如果提供了 start 引數,則從該字元索引開始。如果指定了 N,則返回模式的第 N 次匹配,否則返回第一次匹配。 flags 引數是一個可選的文字字串,包含零個或多個單字母標誌,用於更改函式行為。支援的標誌在 表 9.24 中描述。對於包含括號子表示式的模式,subexpr 是一個整數,指示哪個子表示式是感興趣的:結果是與該子表示式匹配的子字串。子表示式按其左括號的順序編號。當 subexpr 被省略或為零時,結果是整個匹配,而不考慮括號子表示式。

一些例子

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 編寫的一個軟體包。下面關於正則表示式的描述大部分直接摘自他的手冊。

正則表示式(REs),如POSIX1003.2 中定義,有兩種形式:擴充套件REs 或EREs(大致相當於 egrep 的格式),和基本REs 或BREs(大致相當於 ed 的格式)。PostgreSQL 支援這兩種形式,並且還實現了 POSIX 標準中沒有但由於在 Perl 和 Tcl 等程式語言中可用而廣泛使用的某些擴充套件。REs 使用這些非 POSIX 擴充套件在本文件中被稱為高階REs 或AREs。AREs 幾乎是 EREs 的精確超集,但 BREs 有幾個表示法上的不相容之處(而且功能也大大受限)。我們首先描述 ARE 和 ERE 形式,並指出僅適用於 ARE 的特性,然後描述 BRE 的區別。

注意

PostgreSQL 最初總是假定正則表示式遵循 ARE 規則。然而,可以透過在 RE 模式前面加上一個嵌入式選項來選擇更有限的 ERE 或 BRE 規則,如 第 9.7.3.4 節中所述。這對於與期望嚴格遵循POSIX1003.2 規則的應用程式相容非常有用。

正則表示式被定義為一個或多個由 | 分隔的分支。它匹配可以匹配其中一個分支的任何內容。

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

一個量化原子是可能後面跟著一個量詞原子。沒有量詞時,它匹配原子的匹配。有量詞時,它可以匹配該原子的一些匹配次數。表 9.17 中顯示了可能的原子及其選項。可能的量詞及其含義顯示在 表 9.18 中。

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

表 9.17. 正則表示式原子

原子 描述
(re) (其中 re 是任何正則表示式) 匹配 re 的一個匹配項,該匹配項被記錄以供可能報告
(?:re) 如上所述,但匹配項不被記錄以供報告(一對“非捕獲”括號)(僅限 ARE)
. 匹配任何單個字元
[chars] 一個 方括號表示式,匹配 chars 中的任何一個字元(有關更多詳細資訊,請參見 第 9.7.3.2 節
\k (其中 k 是一個非字母數字字元)匹配該字元作為普通字元,例如 \\ 匹配一個反斜槓字元
\c 其中 c 是字母數字(可能後跟其他字元)是一個 轉義,請參見 第 9.7.3.3 節(僅限 ARE;在 ERE 和 BRE 中,這匹配 c
{ 後面跟一個非數字字元時,匹配左大括號字元 {;後面跟一個數字時,它是 bound 的開頭(見下文)
x 其中 x 是一個沒有其他意義的單個字元,匹配該字元

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

注意

如果 standard_conforming_strings 設定為 off,那麼在字面字串常量中寫入的任何反斜槓都需要加倍。有關更多資訊,請參閱 第 4.1.2.1 節

表 9.18. 正則表示式量詞

量詞 匹配
* 原子出現 0 次或多次的序列
+ 原子出現 1 次或多次的序列
? 原子出現 0 次或 1 次的序列
{m} 原子出現恰好 m 次的序列
{m,} 原子出現 m 次或更多次的序列
{m,n} 原子出現 mn 次(含)的序列;m 不能超過 n
*? * 的非貪婪版本
+? + 的非貪婪版本
?? ? 的非貪婪版本
{m}? {m} 的非貪婪版本
{m,}? {m,} 的非貪婪版本
{m,n}? {m,n} 的非貪婪版本

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

非貪婪 量詞(僅在 ARE 中可用)匹配與其對應的普通(貪婪)量詞相同的可能性,但偏好最少匹配次數而不是最多匹配次數。有關更多詳細資訊,請參見 第 9.7.3.5 節

注意

一個量詞不能緊跟另一個量詞,例如 ** 是無效的。量詞不能出現在表示式或子表示式的開頭,也不能跟在 ^| 之後。

表 9.19. 正則表示式約束

約束 描述
^ 匹配字串的開頭
$ 匹配字串的結尾
(?=re) 正向先行斷言 在匹配 re 的子字串開始的任何點進行匹配(僅限 ARE)
(?!re) 負向先行斷言 在沒有匹配 re 的子字串開始的任何點進行匹配(僅限 ARE)
(?<=re) 正向後行斷言 在匹配 re 的子字串結束的任何點進行匹配(僅限 ARE)
(?<!re) 負向後行斷言 在沒有匹配 re 的子字串結束的任何點進行匹配(僅限 ARE)

先行斷言和後行斷言不能包含 反向引用(參見 第 9.7.3.3 節),並且其中的所有括號都被視為非捕獲。

9.7.3.2. 方括號表示式 #

方括號表示式 是由 [] 包圍的字元列表。它通常匹配列表中的任何單個字元(但請參見下文)。如果列表以 ^ 開頭,則它匹配除列表其餘部分之外的任何單個字元。如果列表中的兩個字元被 - 分隔,這是介於這兩個字元之間(含)的字元的完整範圍的簡寫,具體取決於排序順序,例如 [0-9]ASCII匹配任何十進位制數字。兩個範圍共享一個端點是非法的,例如 a-c-e。範圍非常依賴於排序順序,因此可移植程式應避免依賴它們。

要將字面量 ] 包含在列表中,請使其成為第一個字元(如果使用了 ^,則在其之後)。要包含字面量 -,請使其成為第一個或最後一個字元,或範圍的第二個端點。要將字面量 - 用作範圍的第一個端點,請將其括在 [..] 中,使其成為一個排序元素(見下文)。除了這些字元、一些使用 [ 的組合(見下文)和轉義(僅限 ARE)之外,所有其他特殊字元在方括號表示式中都會失去其特殊含義。特別是,在遵循 ERE 或 BRE 規則時,\ 不是特殊的,儘管在 ARE 中它是特殊的(作為轉義符)。

在方括號表示式中,用 [..] 包圍的排序元素(一個字元、一個被視為單個字元的多字元序列,或兩者的排序序列名稱)代表該排序元素的字元序列。該序列被視為方括號表示式列表的單個元素。這允許包含多字元排序元素的方括號表示式匹配多個字元,例如,如果排序序列包含 ch 排序元素,則 RE [[.ch.]]*c 匹配 chchcc 的前五個字元。

注意

PostgreSQL 目前不支援多字元排序元素。此資訊描述了未來的可能行為。

在方括號表示式中,用 [==] 包圍的排序元素是 等價類,代表所有與該排序元素等效的排序元素的字元序列,包括其自身。(如果沒有其他等效的排序元素,則處理方式如同包圍定界符為 [..]。)例如,如果 o^ 是等價類的成員,則 [[=o=]][[=^=]][o^] 都同義。等價類不能是範圍的端點。

在方括號表示式中,用 [::] 包圍的字元類的名稱代表屬於該類的所有字元的列表。字元類不能用作範圍的端點。該POSIX標準定義了以下字元類名稱:alnum(字母和數字)、alpha(字母)、blank(空格和製表符)、cntrl(控制字元)、digit(數字)、graph(除空格外的可列印字元)、lower(小寫字母)、print(包括空格的可列印字元)、punct(標點符號)、space(任何空白字元)、upper(大寫字母)和 xdigit(十六進位制數字)。這些標準字元類的行為對於 7 位 ASCII 集合中的字元在不同平臺上的表現基本一致。某個非 ASCII 字元是否屬於這些類之一取決於用於正則表示式函式或運算子的 排序規則(參見 第 23.2 節),或者預設情況下資料庫的 LC_CTYPE 區域設定(參見 第 23.1 節)。非 ASCII 字元的分類在不同平臺上可能不同,即使是在名稱相似的區域設定中。(但 C 區域設定從不認為任何非 ASCII 字元屬於這些類中的任何一個。)除了這些標準字元類之外,PostgreSQL 還定義了 word 字元類,它與 alnum 加上下劃線(_)字元相同,以及 ascii 字元類,它只包含 7 位 ASCII 集合。

有兩個特殊的方括號表示式:方括號表示式 [[:<:]][[:>:]] 是約束,分別匹配單詞開頭和結尾的空字串。單詞定義為一系列單詞字元,這些字元既不被單詞字元 precede 也不被單詞字元 follow。單詞字元是屬於 word 字元類的任何字元,即任何字母、數字或下劃線。這是對 1003.2 的擴充套件,與之相容但未在其中指定,應謹慎用於打算移植到其他系統的軟體。下面描述的約束轉義通常更可取;它們不比標準更標準,但輸入更方便。POSIX9.7.3.3. 正則表示式轉義 #

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

字元輸入轉義 旨在方便在 RE 中指定非列印字元和其他不方便的字元。它們顯示在 表 9.20 中。

類簡寫轉義 為某些常用的字元類提供了簡寫。它們顯示在 表 9.21 中。

一個 約束轉義 是一個約束,如果滿足特定條件,則匹配空字串,它被寫成一個轉義。它們顯示在 表 9.22 中。

一個 反向引用\n)匹配由數字 n 指定的先前圓括號括起來的子表示式匹配的相同字串(參見 表 9.23)。例如,([bc])\1 匹配 bbcc,但不匹配 bccb。子表示式必須完全出現在 RE 中的反向引用之前。子表示式按其前導括號的順序編號。非捕獲括號不定義子表示式。反向引用僅考慮由被引用子表示式匹配的字串字元,而不考慮其中的任何約束。例如,(^\d)\1 將匹配 22

表 9.20. 正則表示式字元輸入轉義

\a

轉義 描述
警報(響鈴)字元,如 C 中 退格,如 C 中
\b \B
反斜槓(\)的同義詞,以幫助減少反斜槓加倍的需求 \cX
(其中 X 是任何字元)低 5 位與 X 相同,其他位全為零的字元 \e
排序名稱為 ESC 的字元,或者在沒有該名稱的情況下,值為八進位制 033 的字元 換頁符,如 C 中
\f 換行符,如 C 中
\n 回車符,如 C 中
\r 水平製表符,如 C 中
\t \uwxyz
(其中 wxyz 是正好四個十六進位制數字)值為 0xwxyz 的字元 \Ustuvwxyz
(其中 stuvwxyz 是正好八個十六進位制數字)值為 0xstuvwxyz 的字元 \v
垂直製表符,如 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。對於其他多位元組編碼,字元輸入轉義通常只指定字元的位元組值的串聯。如果轉義值不對應於資料庫編碼中的任何合法字元,則不會引發錯誤,但它永遠不會匹配任何資料。

字元輸入轉義始終被視為普通字元。例如,在 ASCII 中 \135],但 \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;但如果 flags 引數指定了 ERE 或 BRE 模式,則有影響。)如果 RE 以 ***= 開頭,則 RE 的其餘部分被視為字面字串,所有字元都視為普通字元。

ARE 可以以 嵌入式選項 開頭:序列 (?xyz)(其中 xyz 是一個或多個字母字元)指定影響 RE 其餘部分(的)選項。這些選項覆蓋任何先前確定的選項 — 特別是,它們可以覆蓋由 regex 運算子隱含的區分大小寫行為,或 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)是非貪婪的(偏好最短匹配)。

  • 一個分支 — 即,沒有頂級 | 運算子的 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,""}

這也行不通,因為現在整個正則表示式都是非貪婪的,所以它會盡快結束整個匹配。我們可以透過強制整個正則表示式貪婪來達到我們的目的。

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

將整個正則表示式的貪婪度與其元件的貪婪度分開控制,可以為處理可變長度模式提供極大的靈活性。

在決定什麼是一個更長或更短的匹配時,匹配長度是以字元而不是排序元素來衡量的。空字串比完全沒有匹配更長。例如:bb* 匹配 abbbc 的中間三個字元;(week|wee)(night|knights) 匹配 weeknights 的全部十個字元;當 (.*).*abc 匹配時,括號括起來的子表示式匹配全部三個字元;當 (a*)*bc 匹配時,整個正則表示式和括號括起來的子表示式都匹配一個空字串。

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

如果指定了換行敏感匹配,. 和使用 ^ 的括號表示式將永遠不會匹配換行符(因此除非正則表示式顯式包含換行符,否則匹配不會跨越多行),並且 ^$ 將分別匹配換行符之後和之前的空字串,此外還將分別匹配字串的開頭和結尾。但 ARE 轉義符 \A\Z 繼續匹配字串的開頭或結尾。此外,字元類簡寫 \D\W 將匹配換行符,而不管此模式如何。(在 PostgreSQL 14 之前,它們在換行敏感模式下不匹配換行符。要獲得舊的行為,請寫入 [^[:digit:]][^[:word:]]。)

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

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

9.7.3.6. 限制和相容性 #

在此實現中,對正則表示式的長度沒有施加任何特定限制。但是,旨在高度可移植的程式不應使用長度超過 256 位元組的正則表示式,因為符合 POSIX 的實現可以拒絕接受此類正則表示式。

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
字串 LIKE_REGEX 模式 regexp_like(字串, 模式)字串 ~ 模式
OCCURRENCES_REGEX(模式 IN 字串) regexp_count(字串, 模式)
POSITION_REGEX(模式 IN 字串) regexp_instr(字串, 模式)
SUBSTRING_REGEX(模式 IN 字串) regexp_substr(字串, 模式)
TRANSLATE_REGEX(模式 IN 字串 WITH 替換) regexp_replace(字串, 模式, 替換)

PostgreSQL 提供的類似正則表示式函式也在許多其他 SQL 實現中可用,而 SQL 標準函式則不那麼普遍。每種實現中的正則表示式語法細節很可能有所不同。

SQL 標準運算子和函式使用 XQuery 正則表示式,這與上面描述的 ARE 語法非常接近。現有的基於 POSIX 的正則表示式功能與 XQuery 正則表示式之間值得注意的差異包括:

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

  • 不支援 XQuery 字元類簡寫 \c\C\i\I

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

  • POSIX 根據當前的區域設定解釋字元類,如 \w(參見 表 9.21)(您可以透過將 COLLATE 子句附加到運算子或函式來控制)。XQuery 透過引用 Unicode 字元屬性來指定這些類,因此只有在遵循 Unicode 規則的區域設定中才能獲得等效行為。

  • SQL 標準(而不是 XQuery 本身)嘗試處理比 POSIX 更多的“換行符”變體。上面描述的換行敏感匹配選項僅將 ASCII NL (\n) 視為換行符,但 SQL 要求我們也將其視為 CR (\r)、CRLF (\r\n)(Windows 風格的換行符)以及一些僅限 Unicode 的字元,如行分隔符 (U+2028)。值得注意的是,根據 SQL,.\s 應將 \r\n 計為一個字元而不是兩個。

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

  • XQuery 不支援括號表示式中的字元類 [:name:] 語法。

  • XQuery 沒有前瞻或後顧約束,也沒有 表 9.22 中描述的任何約束轉義符。

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

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

    • XQuery 的 s(允許點匹配換行符)和 m(允許 ^$ 匹配換行符)標誌提供了與 POSIX 的 npw 標誌相同的行為,但它們 匹配 POSIX 的 sm 標誌的行為。特別要注意的是,點匹配換行符是 POSIX 中的預設行為,但在 XQuery 中不是。

    • XQuery 的 x(忽略模式中的空白字元)標誌與 POSIX 的擴充套件模式標誌明顯不同。POSIX 的 x 標誌還允許 # 開始模式中的註釋,並且 POSIX 不會忽略反斜槓後的空白字元。

提交更正

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