9.7. パターンマッチング

PostgreSQLには、パターンマッチングを行うに際して3つの異なった手法があります。 伝統的なSQLLIKE演算子、これより新しいSIMILAR TO演算子(SQL:1999で追加)、およびPOSIX様式の正規表現です。 更に、SIMILAR TO様式もしくはPOSIX様式正規表現を使って、パターンマッチング関数substringを使用することも可能です。

ティップ: 上記の手法では検索できないようなパターンマッチングが必要な場合は、PerlもしくはTclでユーザ定義関数を作成することを検討してください。

9.7.1. LIKE

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

それぞれのpatternは、文字列の集合を定義します。 LIKE式はpatternによって示される文字列の集合にstringが含まれていれば真を返します。 (想像される通り、NOT LIKE式はLIKE式が真を返す場合には偽を返し、その逆もまた同じです。 同等の式としてNOT (string LIKE pattern)とも表現できます。)

patternがパーセント記号もしくはアンダースコアを含んでいない場合patternは自身の文字列そのものです。 この場合LIKE式は等号演算子のように振舞います。 patternの中にあるアンダースコア(_)は任意の一文字とのマッチを意味し、パーセント記号(%)は0文字以上の文字列とのマッチを意味します。

以下にいくつか例を示します。

'abc' LIKE 'abc'    true
'abc' LIKE 'a%'     true
'abc' LIKE '_b_'    true
'abc' LIKE 'c'      false

LIKEによるパターンマッチは常に文字列全体に対して行われます。 ですから、文字列内の任意位置における並びとマッチさせるにはパーセント記号を先頭と末尾に付ける必要があります。

アンダースコアやパーセント記号というリテラルを他の文字のマッチングに使用するのではなく、そのものにマッチさせたい場合には、patternの中のそれぞれのアンダースコアとパーセント記号の前にエスケープ文字を付けなければなりません。 デフォルトのエスケープ文字はバックスラッシュですが、ESCAPE句で他の文字を指定することができます。 エスケープ文字そのものをマッチさせるにはエスケープ文字をふたつ書きます。

リテラル文字列においてバックスラッシュには始めから特別な意味合いがあるので、バックスラッシュを含んだパターン定数を記述する時は問い合わせの中で2つのバックスラッシュを記述する必要があることに注意してください。 従って、実際にバックスラッシュそのものにマッチするパターンを記述するには、文の中でバックスラッシュを4つ記述する必要があります。 ESCAPE句で他のエスケープ文字を選択すればこのような状況を回避でき、バックスラッシュはLIKE式にとり特殊な文字ではなくなります。 (とはいっても、リテラル文字列パーサにとっては依然として特殊文字なので、やはり2つは必要です。)

同時にESCAPE ''と記述することでエスケープ文字を選択しないことも可能です。 これにより、事実上エスケープ機構が働かなくなります。 つまり、パターン内のアンダースコアおよびパーセント記号の特別な意味を解除することはできなくなります。

現在のロケールに従って大文字小文字を区別しないマッチを行うのであればLIKEの替わりにILIKEキーワードを使うことができます。 これは標準SQLではなく、PostgreSQLの拡張です。

~~演算子はLIKE式と等価で、~~*ILIKEに対応します。 またNOT LIKEおよびNOT ILIKEを表す!~~および!~~*演算子があります。 これら全ての演算子はPostgreSQL固有のものです。

9.7.2. SIMILAR TO正規表現

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

SIMILAR TO演算子は、そのパターンが与えられた文字列にマッチするかどうかにより、真もしくは偽を返します。 これは、標準SQLの正規表現定義を使用してパターンを解釈するという点以外は、LIKEに非常によく似ています。 SQLの正規表現は、LIKE表記と一般的な正規表現の表記とを混ぜ合わせたようなものになっています。

LIKEと同様、SIMILAR TO演算子は、そのパターンが文字列全体にマッチした場合のみ処理を行ないます。 これは、パターンが文字列の一部分であってもマッチする、一般的な正規表現の処理とは異なっています。 また、LIKEと同様、SIMILAR TOでは、%および_を、それぞれ任意の文字列および任意の単一文字を意味するワイルドカード文字として使用します(これらは、POSIX正規表現での.*および.に相当します)。

LIKEから取り入れた上記の機能に加え、SIMILAR TOでは、以下のように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

3つのパラメータを持つsubstring関数、substring(string from pattern for escape-character)を使用して、SQL正規表現パターンにマッチする部分文字列を取り出すことができます。 SIMILAR TOと同様、指定したパターンがデータ文字列全体にマッチする必要があります。 マッチしない場合、関数は終了し、NULLを返します。 マッチした場合に返されるべきパターンの一部を示すために、エスケープ文字の後に二重引用符(")をつなげたものを2つパターンに含める必要があります。 これらの印で囲われたパターンの一部にマッチするテキストが返されます。

以下にいくつか例を示します。

substring('foobar' from '%#"o_b#"%' for '#')   oob
substring('foobar' from '#"o_b#"%' for '#')    NULL

9.7.3. POSIX正規表現

表9-11に、POSIX正規表現を使ったパターンマッチングに使用可能な演算子を列挙します。

表 9-11. 正規表現マッチ演算子

演算子説明
~ 正規表現にマッチ、大文字小文字の区別あり'thomas' ~ '.*thomas.*'
~* 正規表現にマッチ、大文字小文字の区別なし'thomas' ~* '.*Thomas.*'
!~ 正規表現にマッチしない、大文字小文字の区別あり'thomas' !~ '.*Thomas.*'
!~* 正規表現にマッチしない、大文字小文字の区別なし'thomas' !~* '.*vadim.*'

POSIX正規表現は、パターンマッチングという意味合いでは、LIKEおよびSIMILAR TO演算子よりも更に強力です。 egrepsed、あるいはawkのような多くのUnixツールはここで解説しているのと類似したパターンマッチング言語を使用しています。

正規表現とは文字列の集合(正規集合)の簡略された定義である文字が連なっているものです。 ある文字列が正規表現で記述された正規集合の要素になっていれば、その文字列は正規表現にマッチしていると呼ばれます。 LIKEと同様、正規表現言語で特殊文字とされているもの以外、パターン文字は文字列と完全にマッチされます。 とはいっても正規表現はLIKE関数が使用するものと異なる特殊文字を使用します。 LIKE関数のパターンと違って正規表現は、明示的に正規表現が文字列の最初または最後からと位置指定されていない限り文字列内のどの位置でもマッチを行えます。

以下にいくつか例を示します。

'abc' ~ 'abc'    true
'abc' ~ '^a'     true
'abc' ~ '(b|d)'  true
'abc' ~ '^(b|c)' false

2つのパラメータを持つsubstring関数、substring(string from pattern)を使用して、POSIX正規表現パターンにマッチする部分文字列を取り出すことができます。 この関数は、マッチするものがない場合にはNULLを返し、ある場合はパターンにマッチしたテキストの一部を返します。 しかし、任意の括弧を持つパターンの場合、最初の括弧内部分正規表現(左括弧が最初に来るもの)にマッチするテキストの一部が返されます。 この例外を起こさずにパターン中に括弧を使用したいのであれば、常に正規表現全体を括弧で囲むことができます。 パターン内の抽出対象の部分文字列より前に括弧が必要な場合、後述の捕捉されない括弧を参照してください。

以下にいくつか例を示します。

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

PostgreSQLの正規表現はHenry Spencerにより作成されたパッケージを使用して実装されました。 以下の正規表現の説明の多くは、このパッケージのマニュアル項目からコピーされました。

9.7.3.1. 正規表現の詳細

POSIX 1003.2の定義によると、正規表現(RE)には2つの形式があるとされます。 拡張REもしくはERE(大まかにいってegrepに代表されるもの)、および、基本REもしくはBRE(大まかにいってedに代表されるもの)です。 PostgreSQLは両方の形式をサポートし、更に、POSIX標準にはないがPerlやTclなどのプログラミング言語で利用できることより広く使用されるようになった、いくつかの拡張もサポートしています。 本書では、非POSIX拡張を使用したRE最新REもしくはAREと呼びます。 AREはEREの正確な上位セットですが、BREとは複数の記法上の非互換な点があります(更に非常に多くの制限がされています)。 まず、AREとERE形式について説明し、そして、AREにのみ適用される機能の注意を、更にBREとの違いについてを説明します。

注意: PostgreSQLで受け入れられる正規表現の形式はregex_flavor実行時パラメータの設定で選択することができます。 通常の設定はadvancedです。 しかし、extendedを選択して、PostgreSQLリリース7.4より前のリリースとの後方互換性を最大にすることもできます。

正規表現は|で区切られた、ひとつまたは複数のブランチとして定義されます。 ブランチの一つとでもマッチすればマッチしたことになります。

ブランチはゼロ個以上の量指定付きアトムもしくは制約の連結です。 最初のものにマッチし、その次にマッチし、というふうにマッチされます。 なお、空のブランチは空文字にマッチします。

量指定付きアトムとは、単一の量指定子が後ろに付くアトムのことです。 量指定子がないと、アトムに一致するものがマッチしたことになります。 量指定子がある場合、アトムとの一致が何回あるかでマッチしたことになります。 アトムは、表9-12に示したもののいずれかを取ることができます。 表9-13に設定可能な量指定子とその意味を示します。

制約は空文字に、特定の条件に合う場合のみにマッチします。 アトムが使用できる所で制約を使用することができます。 ただし、その後に量指定子を付けることはできません。 単純な制約を表9-14に示します。 後で他のいくつかの制約を説明します。

表 9-12. 正規表現のアトム

アトム説明
(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は他に意味を持たない一文字です。 xにマッチします。

REは\を終端とすることはできません。

注意: PostgreSQLの文字列リテラル内のバックスラッシュ(\)が既に特別な意味を持っていることを忘れないでください。 バックスラッシュを含むパターン定数を書く時には、その文内では2つのバックスラッシュを書かなければなりません。

表 9-13. 正規表現量指定子

量指定子マッチ
* アトムの0個以上の並びにマッチ
+ アトムの1個以上の並びにマッチ
? アトムの0個または1個の並びにマッチ
{m} アトムの正確にm個の並びにマッチ
{m,} アトムのm個以上の並びにマッチ
{m,n} アトムのm個以上n以下の並びにマッチ。 mnを越えることはできません。
*? *の欲張らないバージョン
+? +の欲張らないバージョン
?? ?の欲張らないバージョン
{m}? {m}の欲張らないバージョン
{m,}? {m,}の欲張らないバージョン
{m,n}? {m,n}の欲張らないバージョン

{...}を使用する形式はバウンドと呼ばれます。 バウンド内のmnという数はは符号無し10進整数であり、0以上255以下の値を取ることができます。

欲張らない量指定子(AREのみで使用可能)は、対応する通常の(欲張りの)ものと同じものにマッチしますが、最長のマッチではなく最少のマッチをとります。 詳細は項9.7.3.5を参照してください。

注意: 量指定子の直後に量指定子を続けることはできません。 量指定子から式や副式を始めることはできず、また、^|の直後に付けることもできません。

表 9-14. 正規表現制約

制約説明
^ 文字列の先頭にマッチ
$ 文字列の末尾にマッチ
(?=re) 先行肯定検索は、reにマッチする部分文字列から始まる任意の場所にマッチします。
(?!re) 先行否定検索は、reにマッチしない部分文字列から始まる任意の場所にマッチします。

先行検索制約には後方参照(項9.7.3.3参照)を含めることはできません。 また、その中の括弧は全て取り込むものではないとみなされます。

9.7.3.2. ブラケット式

ブラケット式とは、[]内の文字のリストです。 通常これはそのリスト内の任意の一文字にマッチします。(しかし、以降を参照してください。) リストが^から始まる場合、そのリストの残りには無い任意の一文字にマッチします。 リスト内の2文字が-で区切られていた場合、これは2つ(を含む)の間にある文字範囲全体を表す省略形となります。 例えば、ASCIIにおける[0-9]は全ての数字にマッチします。 例えばa-c-eといった、終端を共有する2つの範囲は不正です。 範囲は並びの照合順に非常に依存しています。 ですので、移植予定のプログラムではこれに依存してはなりません。

このリストに]そのものを含めるには、それを先頭文字(もしあれば^の後の文字)にしてください。 -そのものを含めるには、それを先頭もしくは末尾の文字とするか、範囲の2番目の終端としてください。 -を範囲の1番目の終端で使用するには、[..]でそれを囲み、照合要素(後述)にしてください。 これらの文字には例外があり、[(次段落を参照)、エスケープ(AREのみ)、他の全ての特殊文字の組合せはブラケット式内では特殊な意味を持ちません。 特に、\はEREとBRE規則に従う場合は特別でなくなります。 しかし、AREでは(エスケープの始まりとして)特別な意味を持ちます。

ブラケット式内に、照合要素(文字、単一文字であるかのように照合する複数文字の並び、もしくはそれぞれの照合並びの名前)が[..]の間にあると、その照合要素の文字の並びを意味します。 この並びはブラケット式のリストの一要素です。 こうして、要素を照合する複数文字を含むブラケット式は1文字以上にマッチすることができます。 例えば、照合並びがch照合要素を含む場合、正規表現[[.ch.]]*cchchccという文字の最初の5文字にマッチします。

注意: 今の所、PostgreSQLは複数文字照合要素を持ちません。 この情報は将来の振舞いの可能性を説明したものです。

ブラケット式内の[==]の間に照合要素は同値クラスです。 全ての照合要素の文字の並びが自身を含むものと等価であることを示します。 (他に等価な照合要素がある場合、[..]で囲まれたかのように扱われます。) 例えば、[[=o=]][[=^=]]および[o^]が全て同意語であれば、o^は同値クラスのメンバです。 同値クラスは範囲の終端にはなりません。

ブラケット式内では、[::]の間にある文字クラスの名称は、そのクラスに属する全ての文字のリストを意味します。 標準文字クラス名は、alnumalphablankcntrldigitgraphlowerprintpunctspaceupperxdigitです。 これらはctypeで定義された文字クラスを意味します。 ロケールは別のものを提供する可能性があります。 文字クラスは範囲の終端では使用することができません。

ブラケット式には2つの特殊な場合があります。 [[:<:]][[:>:]]というブラケット式は、先頭と終端の単語がそれぞれ空文字であることにマッチする制約です。 単語は、単語文字が前後に付かない単語文字の並びとして定義されます。 単語文字とは1つのalnum文字です。 (ctypeで定義されています。) これは、POSIX 1003.2との互換性はありますが、そこでは定義されていない式です。 ですので、他システムへ移植予定のソフトウェアでの使用には注意が必要です。 通常後述の制約エスケープの方が良く使われます。 (これも標準ではありませんが、入力しやすくなっています。)

9.7.3.3. 正規表現エスケープ

エスケープとは、\から始まり英数字がその後に続く特殊な並びです。 エスケープには、文字エントリ、クラス省略、制約エスケープ、後方参照といった様々な変種があります。 \の後に英数字が続くが、有効なエスケープを構成しない並びはAREでは不正です。 EREにはエスケープはありません。 ブラケット式の外側では、\の後に英数字が続く並びは単に普通の文字としてその文字を意味します。 ブラケット式の内側では、\は普通の文字です。 (この文字はEREとARE間の非互換性の1つです。)

文字エントリエスケープは非印字文字やRE内で不便な文字の指定を簡略化するために存在します。 これらを表9-15に示します。

クラス省略エスケープは、あるよく使用される文字クラスの省略形を提供します。 これらを表9-16に示します。

制約エスケープは、指定した条件に合う場合に空文字にマッチする制約をエスケープとして表したものです。 これらを表9-17に示します。

後方参照(\n)は、直前に括弧で囲まれた副式によってマッチされた、n番目の同一文字列にマッチします。 (表9-18を参照してください。) 例えば、([bc])\1bbもしくはccにマッチしますが、bccbにはマッチしません。 REでは副式全体は後方参照の前になければなりません。 副式は開括弧の順番で番号付けされます。 取り込まない括弧は副式を定義しません。

注意: エスケープの先頭の\をSQL文字定数としてパターンに入力する時には二重にしなければならないことを忘れないでください。 以下に例を示します。

'123' ~ '^\\d{3}' true

表 9-15. 正規表現文字エントリエスケープ

エスケープ説明
\a 警報(ベル)文字。C言語と同じ
\b バックスペース。C言語と同じ
\B バックスラッシュの必要な二重化回数を減らすための\の同義語
\cX (ここでXは任意の文字です。) その下位5ビットがXと同一、その他のビットが0となる文字
\e 照合順名がESCとなる文字、それに失敗したら、033という8進数値を持つ文字。
\f 改ページ、C言語と同じ
\n 改行、C言語と同じ
\r 復帰、C言語と同じ
\t 水平タブ、C言語と同じ
\uwxyz (ここでwxyzは正確に4桁の16進数です。) 使用マシンのバイト順で表した、U+wxyzというUnicode文字
\Ustuvwxyz (ここでstuvwxyzは正確に8桁の16進数です。) 何らかの仮定のために確保されたUnicode拡張、32ビット
\v 垂直タブ、C言語と同じ
\xhhh (ここでhhhは任意の16進数の並びです。) その文字の16進数値が0xhhhとなる文字。 (使用される16進数の桁数に関わらず単一の文字。)
\0 その値が0となる文字
\xy (ここでxyは正確に2桁の8進数で、後方参照ではありません。) その値が0xyとなる文字
\xyz (ここでxyzは正確に3桁の8進数で、後方参照ではありません。) その値が0xyzとなる文字

16進数の桁とは0-9a-fA-Fです。 8進数の桁とは0-7です。

この文字エントリエスケープは常に普通の文字と解釈されます。 例えば、\135はASCIIの]となり、\135はブラケット式の終端にはなりません。

表 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:]]と同じになり、不正です。)

表 9-17. 正規表現制約エスケープ

エスケープ説明
\A 文字列の先頭にのみマッチします。 (^との違いについては項9.7.3.5を参照してください。)
\m 単語の先頭にのみマッチします。
\M 単語の末尾にのみマッチします。
\y 単語の先頭もしくは末尾にのみマッチします。
\Y 単語の先頭もしくは末尾以外の場所にのみマッチします。
\Z 文字列の末尾にのみマッチします。 ($との違いについては項9.7.3.5を参照してください。)

単語は前述の[[:<:]][[:>:]]の規定通りに定義されます。 ブラケット式内では制約エスケープは不正です。

表 9-18. 正規表現後方参照

エスケープ説明
\m (ここでmは非ゼロの数です。) 副式のm番目への後方参照
\mnn (ここでmは非ゼロの数です。 nnで更に桁を指定します。 mnn10進数値は取り込み括弧の数よりも多くてはなりません。) 副式のmnn番目への後方参照

注意: 8進数の文字エントリエスケープと後方参照の間には歴史的な曖昧性があります。 上でヒントして示したようにこれは発見的手法で解決されます。 先頭の0は常に8進数エスケープを示します。 その後に数字が続かない単一の非ゼロ数字は常に後方参照として解釈されます。 ゼロから始まらない複数数字の並びは、適切な副式の後にあれば(つまり、その番号が後方参照用の範囲内にあれば)後方参照として解釈されます。 さもなくば、8進数として解釈されます。

9.7.3.4. 正規表現メタ構文

上述の主構文の他に、特殊な形式や雑多な構文的な機能が使用可能です。

通常、使用されるREの種類はregex_flavorで決定されます。 しかし、決定子前置詞によって上書きすることができます。 REが***:から始まるものであれば、regex_flavorに関係なく、REの残りはAREと解釈されます。 REが***=から始まるものであれば、REの残りは、全ての文字を普通の文字とみなしたリテラル文字列と解釈されます。

AREは埋め込みオプションから始めることもできます。 (?xyz)という並びで残りのREに影響するオプションを指定します。 (ここでxyzは1つ以上の英字です。) このオプションは、事前に決定された(RE種類や大文字小文字の区別を含む)オプションを上書きします。 使用可能なオプション文字を表9-19に示します。

表 9-19. 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のコメント付けが可能になります。 基本規則に対して3つの例外があります。

  • 直前に\が付いた空白文字もしくは#は保持されます。

  • ブラケット式内の空白文字もしくは#は保持されます。

  • (?:などの複数文字シンボルでは、空白文字とコメントは不正です。

ここでの空白文字とは、空白、タブ、改行、space文字クラスに属する文字です。

最後に、AREのブラケット式の外側では、(?#ttt)という並びはコメントになります。 (ここでttt)を含まない任意のテキストです。) 繰り返しになりますが、これは(?:などの複数文字シンボルの文字間では使用できません。 こうしたコメントは実用性よりも歴史的な加工品です。 そのため、この使用は勧めません。代わりに拡張構文を使用してください。

初めに***=決定子が指定され、ユーザの入力がREではなくリテラルとして扱われる場合、これらのメタ構文拡張は使用できません

9.7.3.5. 正規表現マッチ規則

REが文字列の中の1つ以上の部分文字列とマッチする場合において、REは最初にマッチが始まった部分文字列とマッチします。 その位置からまた1つ以上の部分文字列とマッチした際は、正規表現は欲張り欲張りでないnon-greedyかによって、最長一致もしくは最短一致の文字列のどちらにマッチします。

REが欲張りか欲張りでないかは以下の規則によって決まります。

  • ほとんどのアトムおよび全ての式は欲張り属性を持ちません。 (これらは変動する量のテキストにまったくマッチしないからです。)

  • REを括弧で括ることは欲張りかどうかを変更しません。

  • {m}もしくは{m}?といった固定繰り返し数の量指定子を持つ量指定付きアトムは、アトム自身と同一の欲張りさを持ちます。(全く持たない可能性もあります。)

  • 他の通常の量指定子({m,n}mnが等しい場合も含みます)を持つ量指定付きアトムは欲張りです。(最長マッチを使用します。)

  • 他の欲張らない量指定子({m,n}?mnが等しい場合も含みます)を持つ量指定付きアトムは欲張りではありません。(最短マッチを使用します。)

  • 最上位レベルの|演算子を持たないREであるブランチは、最初の欲張り属性を持つ量指定付きアトムと同一の欲張り属性を持ちます。

  • |演算子で接続された2つ以上のブランチからなるREは常に欲張りです。

上の規則は、個々の量指定付きアトムだけではなく、量指定付きアトムを複数含むブランチやRE全体の欲張り属性に関連します。 つまり、ブランチやRE全体が全体として最長または最短の部分文字列にマッチするという方法でマッチ処理が行われます。 全体のマッチの長さが決まると、特定の部分式にマッチする部分がその部分式の欲張り属性によって決まります。 この時、RE内でより前にある部分式が後にある部分式よりも高い優先度を持ちます。

この意味の例を示します。

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

最初の例では、Y*が欲張りであるため、REは全体として欲張りです。 マッチはYの位置から始まり、そこから可能な限り最長の文字列にマッチします。 つまりY123となります。 出力は括弧で括られた部分、つまり123となります。 2番目の例では、Y*?が欲張りでないため、REは全体として欲張りではありません。 マッチはYの位置から始まり、そこから可能な限り最短の文字列にマッチします。 つまりY1となります。 部分式[0-9]{1,3}は欲張りですが、決定されたマッチする全体の長さを変更することはできません。 従って、強制的に1にマッチすることになります。

まとめると、REが欲張りな部分式と欲張りではない部分式を持つ場合、全体のマッチ長はRE全体に割り当てられる属性に応じて、最長マッチ長か最短マッチ長のどちらかになります。 部分式に割り当てられた属性は、部分式の中でどれだけの量をその部分式の中で"消費"できるかのみに影響します。

{1,1}および{1,1}?量指定子を副式もしくはRE全体に使用して、それぞれ、欲張りか欲張りでないかを強制することが可能です。

マッチの長さ照合要素ではなく文字列で測られます。 空文字列は全くマッチする要素がない文字列よりも長いと考えられます。 例えば、bb*abbbcの真中の3文字とマッチし、(week|wee)(night|knights)weeknightsの全ての10文字とマッチし、abcに対して(.*).*がマッチされると、括弧内の部分正規表現は3つの文字全てにマッチし、bcに対して(a*)*がマッチされると、全体のREと括弧内の正規表現は空文字列にマッチします。

もし大文字小文字を区別しないマッチングが指定されると、アルファベット文字の大文字小文字の区別が全くなくなったと同じ効果をあたえます。 ブラケット式の外側にアルファベットの大文字小文字が混ざった通常の文字が出てきた場合、例えば、x[xX]となるように大文字小文字ともにブラケット式に実質的に転換されます。 ブラケット式の中に現われた時は、(例えば、)[x][xX]となり、また[^x][^xX]となるように、全ての大文字小文字それぞれの対がブラケット式に追加されます。

改行を区別するマッチが指定されると、.^を使用するブラケット式は(REが明示的に調整されていたとしてもマッチが改行を跨らないようにするために)改行文字にマッチしなくなります。 また、^$はそれぞれ改行直後と直前の空文字列にマッチし、更に、それぞれ文字列の先頭と末尾にマッチします。 しかし、AREエスケープの\A\Zは、継続して、文字列の先頭と末尾のみにマッチします。

部分的に改行を区別するマッチが指定されると、.とブラケット式は改行を区別するマッチを行なうようになりますが、^$は変更されません。

部分的に改行を逆区別するマッチが指定されると、 ^$は改行を区別するマッチを行なうようになりますが、.とブラケット式は変更されません。 これはあまり有用ではありません。対称性のために提供されています。

9.7.3.6. 制限と互換性

本実装ではREの長さに関する制限はありません。 しかし、移植性を高めたいプログラムでは、256バイトを越えるREを使用すべきではありません。 POSIX互換の実装ではそうしたREでは混乱する可能性があります。

AREの機能の内、POSIX EREと実質的な非互換性があるのは、\がブラケット式の内側で特殊な意味を失わないという点のみです。 他の全てのARE機能は、POSIX EREでは不正、未定義、未指定な効果となる構文を使用しています。 決定子の***構文などはBREおよびEREのPOSIX構文にはありません。

多くのARE式はPerlから借りられたものです。 しかし、いくつかは整理され、Perlの拡張のいくつかは存在しません。 注意すべき非互換性には、\b\B、改行の取扱いに関する特殊な措置の欠落、改行を区別するマッチに影響する点について補足したブラケット式の追加、括弧と先行検索制約内の後方参照についての制限、最長/最短(最初にマッチするではなく)マッチのセマンティックがあります。

PostgreSQLリリース7.4より前で認知された、AREとERE構文間で大きな非互換な2つあります。

  • AREでは、\の後に英数字が続くものはエスケープもしくはエラーとなります。 以前のリリースでは、これは単に、英数字を記述する他の方法でした。 これは、大きな問題にはならないはずです。 以前のリリースではこうした並びを記述する理由がないからです。

  • AREでは、\[]内でも特別な文字です。 従って、ブラケット式では\\\と記述しなければなりません。

これらの違いによりほとんどのアプリケーションでは問題になることはあまりありませんが、必要に応じてregex_flavorextendedに設定することで回避することができます。

9.7.3.7. 基本正規表現

BREはEREといくつかの面において異なります。 |+?は普通の文字であり、それらの機能と等価なものはありません。 バウンドの区切りは\{\}であり、{}自身は普通の文字です。 副式を入れ子にするための括弧は\(\)であり、()自身は普通の文字です。 ^は、REの先頭にある場合や括弧内の副式の先頭の場合を除き、普通の文字です。 $は、REの末尾にある場合や括弧内の副式の末尾の場合を除き、普通の文字です。 また、*はREの先頭にある場合や括弧内の副式の先頭にある場合には普通の文字になります。(その前に^が付いている可能性もあります。) 最後に、1桁の後方参照を使用することができ、また、\<\>はそれぞれ[[:<:]][[:>:]]と同義です。 他のエスケープは使用できません。