PostgreSQLには、パターンマッチを行うに際して3つの異なった手法があります。伝統的なSQLのLIKE
演算子、これより新しいSIMILAR TO
演算子(SQL:1999で追加されました)、およびPOSIX様式の正規表現です。基本の"この文字列はこのパターンに一致するか?"を別としても、一致した部分文字列を取り出したり置換したり、そして一致部分で文字列を分割する関数が用意されています。
ティップ: 上記の手法では検索できないようなパターンマッチが必要な場合は、PerlもしくはTclでユーザ定義関数を作成することを検討してください。
LIKE
string LIKE pattern [ESCAPE escape-character] string NOT LIKE pattern [ESCAPE escape-character]
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つ書きます。
リテラル文字列においてバックスラッシュには始めから特別な意味合いがあるので、バックスラッシュを含んだパターン定数を記述する時は問い合わせの中で2つのバックスラッシュを記述する必要があることに注意してください(エスケープ文字列構文の使用を前提)。
したがって、実際にバックスラッシュそのものに一致するパターンを記述するには、文の中でバックスラッシュを4つ記述する必要があります。ESCAPE句で他のエスケープ文字を選択すればこのような状況を回避でき、バックスラッシュはLIKE
式にとって特殊な文字ではなくなります(とは言っても、バックスラッシュはリテラル文字列パーサにとっては依然として特殊文字なので、バックスラッシュに一致させるにはやはり2つは必要です)。
同時にESCAPE ''と記述することでエスケープ文字を選択しないことも可能です。 これにより、事実上エスケープ機構が働かなくなります。つまり、パターン内のアンダースコアおよびパーセント記号の特別な意味を解除することはできなくなります。
現在のロケールに従って大文字小文字を区別しない一致を行うのであれば、LIKEの代わりにILIKEキーワードを使うことができます。これは標準SQLではなく、PostgreSQLの拡張です。
~~演算子はLIKE
式と等価で、~~*はILIKE
に対応します。またNOT LIKE
およびNOT ILIKE
を表す!~~および!~~*演算子があります。これら全ての演算子はPostgreSQL固有のものです。
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正規表現から取り入れたパターンマッチメタ文字もサポートしています。
|は、二者択一(2つの選択肢のうちいずれか)を意味します。
*は、直前の項目の0回以上複数の繰り返しを意味します。
+は、直前の項目の1回以上複数の繰り返しを意味します。
丸括弧()は、項目を1つの論理項目にグループ化することができます。
大括弧式[...]は、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-11に、POSIX正規表現を使ったパターン一致に使用可能な演算子を列挙します。
表 9-11. 正規表現マッチ演算子
演算子 | 説明 | 例 |
---|---|---|
~ | 正規表現に一致、大文字小文字の区別あり | 'thomas' ~ '.*thomas.*' |
~* | 正規表現に一致、大文字小文字の区別なし | 'thomas' ~* '.*Thomas.*' |
!~ | 正規表現に一致しない、大文字小文字の区別あり | 'thomas' !~ '.*Thomas.*' |
!~* | 正規表現に一致しない、大文字小文字の区別なし | 'thomas' !~* '.*vadim.*' |
POSIX正規表現は、パターンマッチという意味合いでは、LIKE
およびSIMILAR TO
演算子よりもさらに強力です。egrep、sed、あるいはawkのような多くのUnixツールはここで解説しているのと類似したパターンマッチ言語を使用しています。
正規表現とは文字列の集合(正規集合)の簡略された定義である文字が連なっているものです。ある文字列が正規表現で記述された正規集合の要素になっていれば、その文字列は正規表現に一致していると呼ばれます。LIKE
と同様、正規表現言語で特殊文字とされているもの以外、パターン文字は文字列と完全に一致されます。
とは言っても、正規表現はLIKE
関数が使用するのとは異なる特殊文字を使用します。LIKE
関数のパターンと違って正規表現は、明示的に正規表現が文字列の最初または最後からと位置指定されていない限り文字列内のどの位置でも一致を行えます。
例:
'abc' ~ 'abc' true 'abc' ~ '^a' true 'abc' ~ '(b|d)' true 'abc' ~ '^(b|c)' false
POSIXパターン言語について以下により詳しく説明します。
2つのパラメータを持つsubstring
関数、substring(string from pattern)
を使用して、POSIX正規表現パターンに一致する部分文字列を取り出すことができます。この関数は、一致するものがない場合にはNULLを返し、ある場合はパターンにマッチしたテキストの一部を返します。しかし、任意の丸括弧を持つパターンの場合、最初の丸括弧内部分正規表現(左丸括弧が最初に来るもの)に一致するテキストの一部が返されます。この例外を起こさずにパターン中に丸括弧を使用したいのであれば、常に正規表現全体を丸括弧で囲むことができます。パターン内の抽出対象の部分文字列より前に丸括弧が必要な場合、後述の捕捉されない丸括弧を参照してください。
例:
substring('foobar' from 'o.b') oob substring('foobar' from 'o(.)b') o
regexp_replace
関数は、POSIX正規表現パターンに一致する部分文字列を新規テキストと置換します。
構文は、regexp_replace
(source、pattern、replacement [、flags ])です。
patternにマッチしない場合は、source文字列がそのまま返されます。
一致すると、マッチ部分文字列をreplacement文字列で置換したsource文字列が返されます。
replacementは\nを含むことができます。
ここでnは、n番目に丸括弧で括られたパターンの部分表現に一致する元の部分文字列を示す、 1から9までの数です。
\&が含まれた場合、パターン全体と一致する部分文字列が挿入されることを示します。
置換テキスト内にリテラルバックスラッシュを挿入する必要にある時は\\と記述します。
(いつもの通り、エスケープ文字列構文の使用を前提すると、リテラル定数文字列内ではバックスラッシュを2重にすることを思いだしてください。)
flagsパラメータは、関数の動作を変更するゼロもしくはそれ以上の1文字フラグを含むオプションのテキスト文字列です。フラグiは大文字小文字を区別した一致を指定する一方、フラグgは、最初に一致したもののみではなく、それぞれ一致した部分文字列の置換を指定します。その他の有効なフラグは表9-19に記述されています。
例:
regexp_replace('foobarbaz', 'b..', 'X') fooXbaz regexp_replace('foobarbaz', 'b..', 'X', 'g') fooXX regexp_replace('foobarbaz', 'b(..)', E'X\\1Y', 'g') fooXarYXazY
regexp_matches
関数はPOSIX正規表現パターンマッチの結果捕捉された全ての部分文字列を返します。regexp_matches
(string, pattern
[, flags ])の構文になります。
もしpatternに対して一致しない場合、関数は行を返しません。一致する場合、関数はパターンのn番目に丸括弧で括られた部分文字列に一致する、n番目の要素が部分文字列であるテキスト配列を返します("捕捉されない"丸括弧は数えません)。パターンが丸括弧に括られた部分文字列を含まない場合、結果はパターン全体に一致する部分文字列を含む単一要素のテキスト配列となります。flagsパラメータは、関数の動作を変更するゼロもしくは複数の単一文字フラグを含むオプションのテキスト文字列です。フラグgは関数に、最初のマッチだけでなく文字列の中で全てのマッチを検出させ、それら一致の行を返させます。その他有効なフラグは表9-19に記載されています。
例:
SELECT regexp_matches('foobarbequebaz', '(bar)(beque)'); regexp_matches ---------------- {bar,beque} (1 row) SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); regexp_matches ---------------- {bar,beque} {bazil,barf} (2 rows) SELECT regexp_matches('foobarbequebaz', 'barbeque'); regexp_matches ---------------- {barbeque} (1 row)
regexp_split_to_table
関数はPOSIX正規表現パターンを区切り文字として使用し、文字列を分割します。regexp_split_to_table
(string, pattern
[, flags ])の構文になります。patternに一致しない場合、関数はstringを返します。少なくともひとつの一致があれば、それぞれの一致に対して関数は最後のマッチの終わり(あるいは文字列の始め)から最初のマッチまでのテキストを返します。もはやマッチしなくなると最後のマッチの終わりから文字列の最後までテキストを返します。
flagsパラメータは、関数の動作を変更するゼロもしくは複数の単一文字フラグを含むオプションのテキスト文字列です。regexp_split_to_table
は表9-19で記載されているフラグをサポートします。
regexp_split_to_array
関数は、regexp_split_to_array
がその結果をtext配列で返すことを除いて、regexp_split_to_table
と同じ動作をします。regexp_split_to_array
(string, pattern
[, flags ])の構文になります。
例:
SELECT foo FROM regexp_split_to_table('the quick brown fox jumped over the lazy dog', E'\\s+') AS foo; foo -------- the quick brown fox jumped over the lazy dog (9 rows) SELECT regexp_split_to_array('the quick brown fox jumped over the lazy dog', E'\\s+'); regexp_split_to_array ------------------------------------------------ {the,quick,brown,fox,jumped,over,the,lazy,dog} (1 row) SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo; foo ----- t h e q u i c k b r o w n f o x (16 rows)
最後の例が明らかにしているように、regexp分割関数は文字列の最初あるいは終わり、もしくは前のマッチの直後に発生する長さを持たないマッチを無視します。regexp_matches
で実装されたregexpマッチの厳格な定義にこれは相容れませんが、実務上は最も使い勝手の良い動作です。Perlのような他のソフトウェアシステムも似たような定義を使用します。
PostgreSQLの正規表現はHenry Spencerにより書かれたソフトウェアパッケージを使用して実装されています。以下に説明する正規表現の多くの部分は同氏のマニュアルから一字一句複製したものです。
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でが、PostgreSQLリリース7.4より前のリリースとの後方互換性得るため、extendedを選択することもできます。
正規表現は|で区切られた、1つまたは複数のブランチとして定義されます。ブランチのいずれか1つに一致すれば一致したことになります。
ブランチはゼロ個以上の量化アトムもしくは制約の連結です。最初のものにマッチに、次に第2番目のものにマッチを、というふうに一致します。なお、空のブランチは空文字列に一致します。
量化アトムとは、単一の量指定子が後ろに付くアトムのことです。量指定子がないと、アトムに一致するものが一致したことになります。量指定子がある場合、アトムとの一致が何回あるかで一致したことになります。アトムは、表9-12に示したもののいずれかを取ることができます。表9-13に設定可能な量指定子とその意味を示します。
制約は空文字に、特定の条件に合う場合のみに一致します。 アトムを使用できるところには制約を使用することができます。 ただしその後に量指定子を付けることはできません。 単純な制約を表9-14に示します。後で他のいくつかの制約を説明します。
表 9-12. 正規表現のアトム
アトム | 説明 |
---|---|
(re) | (ここでre は任意の正規表現で、)reとのマッチに適合するもです。 マッチは可能である報告用と意味づけられます。 |
(?:re) | 上と同じ。ただし、一致は報告用と意味づけられません。("捕捉されない"括弧の集合)(AREのみ) |
. | 任意の1文字に一致します。 |
[chars] | ブラケット式。 charsのいずれか1つに一致します (詳細は項9.7.3.2を参照してください)。 |
\k | (ここでkは英数字以外です。)普通の文字として指定した文字に一致します。 例えば、\\はバックスラッシュ文字です。 |
\c | ここでcは英数字です (おそらく他の文字が後に続きます)。 エスケープです。 項9.7.3.3を参照してください (AREのみ、EREとBREではこれはcに一致します)。 |
{ | 直後に数字以外がある場合、左中括弧{に一致します。 直後に数字が続く場合、bound(後述)の始まりです。 |
x | ここでxは他に意味を持たない1文字です。 xに一致します。 |
REは\を終端とすることはできません。
注意: PostgreSQLの文字列リテラル内のバックスラッシュ(\)が既に特別な意味を持っていることを忘れないでください。 エスケープ文字列構文が使用されると仮定すると、バックスラッシュを含むパターン定数を書く時には、その文では2つのバックスラッシュを書かなければなりません(項4.1.2.1を参照ください)。
表 9-13. 正規表現量指定子
量指定子 | マッチ |
---|---|
* | アトムの0個以上複数の並びに一致 |
+ | アトムの1個以上複数の並びに一致 |
? | アトムの0個または1個の並びに一致 |
{m} | アトムの正確にm個の並びに一致 |
{m,} | アトムのm個以上の並びに一致 |
{m,n} | アトムのm個以上n以下の並びに一致。 mはnを超えることはできません。 |
*? | *の最短マッチを行うバージョン |
+? | |
?? | ?の最短マッチを行うバーション |
{m}? | {m}の最短マッチを行うバージョン |
{m,}? | {m,}の最短マッチを行うバーション |
{m,n}? | non-greedy version of {m,n} |
{...}を使用する形式はバウンドとして知られています。バウンド内のmとnという数は符号なし10進整数であり、0以上255以下の値を取ることができます。
最短マッチを行う量指定子(AREのみで使用可能)は、対応する通常の(欲張りの)ものと同じものに一致しますが、最大のマッチではなく最小のマッチを取ります。 詳細は項9.7.3.5を参照してください。
注意: 量指定子の直後に量指定子を続けることはできません。例えば**は無効です。 量指定子から式や副式を始めることはできず、また、^や|の直後に付けることもできません。
表 9-14. 正規表現制約
制約 | 説明 |
---|---|
^ | 文字列の先頭に一致 |
$ | 文字列の末尾に一致 |
(?=re) | 先行肯定検索は、reに一致する部分文字列から始まる任意の場所に一致します(AREのみ)。 |
(?!re) | 先行否定検索は、reに一致しない部分文字列から始まる任意の場所に一致します(AREのみ)。 |
先行検索制約には後方参照(項9.7.3.3を参照)を含めることはできません。また、その中の括弧は全て取り込むものではないとみなされます。
ブラケット式とは、[]内の文字のリストです。通常これはそのリスト内の任意の1文字に一致します(しかし、以降を参照してください)。リストが^から始まる場合、そのリストの残りにはない任意の1文字に一致します。リスト内の2文字が-で区切られていた場合、これは2つ(を含む)の間にある文字範囲全体を表す省略形となります。例えば、ASCIIにおける[0-9]は全ての数字に一致します。例えばa-c-eといった、終端を共有する2つの範囲は不正です。範囲は並びの照合順に非常に依存しています。ですので、移植予定のプログラムではこれに依存してはなりません。
このリストに]そのものを含めるには、それを先頭文字(もしそれが使用されれば^の後)にしてください。-そのものを含めるには、それを先頭もしくは末尾の文字とするか、範囲の2番目の終端としてください。-を範囲の最初の終端で使用するには、[.と.]でそれを囲み、照合要素(後述)にしてください。 これら文字と、[(次段落を参照)のなんらかの組み合わせ、およびエスケープ(AREのみ)を例外として、他の全ての特殊文字はブラケット式内では特殊な意味を持ちません。特に、\はEREとBRE規則に従う場合は特別でなくなります。しかし、AREでは(エスケープの始まりとして)特別な意味を持ちます。
ブラケット式内に、照合要素(文字、単一文字であるかのように照合する複数文字の並び、もしくはそれぞれの照合並びの名前)が[.と.]の間にあると、その照合要素の文字の並びを意味します。この並びはブラケット式のリストの一要素として取り扱われます。このことにより、ブラケット式は要素を照合する複数文字を含むブラケット式を1文字以上に一致させることができます。例えば、照合並びがch照合要素を含む場合、正規表現[[.ch.]]*cはchchccという文字の最初の5文字に一致します。
注意: 今のところ、PostgreSQLは複数文字照合要素をサポートしません。この情報は将来の振舞いの可能性を説明したものです。
ブラケット式内の[=と=]の間に照合要素は同値クラスです。全ての照合要素の文字の並びが自身を含むものと等価であることを示します(他に等価な照合要素がある場合、[.と.]で囲まれたかのように扱われます)。例えば、[[=o=]]、[[=^=]]および[o^]が全て同意語であれば、oと^は同値クラスのメンバです。同値クラスは範囲の終端にはなりません。
ブラケット式内では、[:と:]の間にある文字クラスの名称は、そのクラスに属する全ての文字のリストを意味します。標準文字クラス名は、alnum、alpha、blank、cntrl、digit、graph、lower、print、punct、space、upper、xdigitです。これらはctypeで定義された文字クラスを意味します。ロケールは別のものを提供可能です。文字クラスは範囲の終端では使用することができません。
ブラケット式には2つの特殊な場合があります。[[:<:]]と[[:>:]]というブラケット式は、先頭と終端の単語がそれぞれ空文字であることに一致する制約です。単語は、単語文字が前後に付かない単語文字の並びとして定義されます。単語文字とは1つのalnum文字です(ctypeで定義されています)。これは、POSIX 1003.2との互換性はありますが、そこでは定義されていない式です。ですので、他システムへ移植予定のソフトウェアでの使用には注意が必要です。通常後述の制約エスケープの方がよく使われます。これはもはや標準ではありませんが、入力しやすいものです。
エスケープとは、\から始まり英数字がその後に続く特殊な並びです。エスケープには、文字エントリ、クラス省略、制約エスケープ、後方参照といった様々な変種があります。\の後に英数字が続くけれども、有効なエスケープを構成しない並びはAREでは不正です。EREにはエスケープはありません。ブラケット式の外側では、\の後に英数字が続く並びは単に普通の文字としてその文字を意味します。ブラケット式の内側では、\は普通の文字です(この文字はEREとARE間の非互換性の1つです)。
文字エントリエスケープは非印字文字やRE内でその他の不便な文字の指定を簡略化するために存在します。これらを表9-15に示します
クラス省略エスケープは、あるよく使用される文字クラスの省略形を提供します。これらを表9-16に示します。
制約エスケープは、指定した条件に合う場合に空文字に一致する制約をエスケープとして表したものです。これらを表9-17に示します。
後方参照(\n)は、直前に括弧で囲まれた副式によって一致された、n番目の同一文字列に一致します(表9-18を参照してください)。例えば、([bc])\1はbbもしくはccに一致しますが、bcやcbには一致しません。REでは副式全体は後方参照の前になければなりません。副式は開括弧の順番で番号付けされます。取り込まない括弧は副式を定義しません。
注意: エスケープの先頭の\をSQL文字定数としてパターンに入力する時には二重にしなければならないことを忘れないでください。以下に例を示します。
'123' ~ E'^\\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というUTF16(16ビット、Unicode)文字 |
\Ustuvwxyz | (ここでstuvwxyzは正確に8桁の16進数です。)32ビットにUnicodeが拡張されるという仮説のために確保 |
\v | C言語と同じ垂直タブ |
\xhhh | (ここでhhhは任意の16進数の並びで)その文字の16進数値が0xhhhとなる文字(使用される16進数の桁数にかかわらず単一の文字) |
\0 | その値が0(NULLバイト)となる文字 |
\xy | (ここでxyは正確に2桁の8進数で、後方参照ではない)その値が0xyとなる文字 |
\xyz | (ここでxyzは正確に3桁の8進数で、後方参照ではない)その値が0xyzとなる文字 |
16進数の桁とは0-9、a-f、A-Fです。8進数の桁とは0-7です。
この文字エントリエスケープは常に普通の文字と解釈されます。例えば、\135はASCIIの]となり、\135はブラケット式の終端にはなりません。
表 9-16. 正規表現クラス省略エスケープ
エスケープ | 説明 |
---|---|
\d | [[:digit:]] |
\s | [[:space:]] |
\w | [[:alnum:]_] (note underscore is included) |
\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進数として解釈されます。
上述の主構文の他に、特殊な形式や雑多な構文的な機能が使用可能です。
通常、使用される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つの例外があります。
直前に\が付いた空白文字もしくは#は保持されます。
ブラケット式内の空白文字もしくは#は保持されます。
(?:などの複数文字シンボルでは、空白文字とコメントは不正です。
ここでの空白文字とは、空白、タブ、改行、スペース文字クラスに属する文字です。
最後に、AREのブラケット式の外側では、(?#ttt)という並びはコメントになります(ここでtttは)を含まない任意のテキストです)。繰り返しになりますが、これは(?:などの複数文字シンボルの文字間では使用できません。こうしたコメントは実用性というより歴史的所産です。そのため、この使用は勧めません。代わりに拡張構文を使用してください。
初めに***=決定子が指定され、ユーザの入力がREではなくリテラルとして扱われる場合、これらのメタ構文拡張は使用できません。
REが文字列の中の1つ以上の部分文字列と一致する場合において、REは最初にマッチが始まった部分文字列と一致します。その位置からまた1つ以上の部分文字列とマッチした際は、正規表現は最短マッチを行わない(欲張り型)か最短マッチを行う(非欲張り型)かによって、最長一致もしくは最短一致の文字列のどちらに一致します
REが欲張り型か、非欲張り型かは以下の規則によって決まります。
ほとんどのアトムおよび全ての式は欲張り属性を持ちません(これらは変動する量のテキストにまったく一致しないからです)。
REを括弧で括ることは欲張りかどうかを変更しません。
{m}もしくは{m}?といった固定繰り返し数の量指定子を持つ量指定付きアトムは、アトム自身と同一の欲張りさを持ちます(まったく持たない可能性もあります)。
他の通常の量指定子({m,n}、mとnが等しい場合も含みます)を持つ量指定付きアトムは欲張り型です(最長マッチを使用します)。
他の非欲張り型量指定子({m,n}?、mとnが等しい場合も含みます)を持つ量指定付きアトムは非欲張り型です(最短マッチを使用します)。
最上位レベルの|演算子を持たない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は、継続して、文字列の先頭と末尾のみに一致します。
部分的に改行を区別するマッチが指定されると、.とブラケット式は改行を区別する一致を行うようになりますが、^と$は変更されません。
部分的に改行を区別する逆マッチが指定されると、^と$は改行を区別する一致を行うようになりますが、.とブラケット式は変更されません。これはあまり有用ではありません。対称性のために提供されています。
本実装では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_flavorをextendedに設定することで回避することができます。
BREはEREといくつかの面において異なります。BREにおいては、 |、+、?は普通の文字であり、それらの機能と等価なものはありません。 バウンドの区切りは\{と\}であり、{と}自身は普通の文字です。 副式を入れ子にするための括弧は\(と\)であり、(と)自身は普通の文字です。 ^は、REの先頭にある場合や括弧内の副式の先頭の場合を除き、普通の文字です。 $は、REの末尾にある場合や括弧内の副式の末尾の場合を除き、普通の文字です。 また、*はREの先頭にある場合や括弧内の副式の先頭にある場合には普通の文字になります(その前に^が付いている可能性もあります)。 最後に、1桁の後方参照を使用することができ、また、BREにおいては、\<と\>はそれぞれ[[:<:]]と[[:>:]]と同義です。