この章では、正規表現と、データベース・アプリケーションにおけるその使用方法について説明します。
内容は次のとおりです。
参照:
|
正規表現は、メタキャラクタ(演算子または演算子に属する)および文字リテラルを使用する検索パターンを指定します(『Oracle Database SQL言語リファレンス』を参照)。
検索パターンは複雑なものが可能です。たとえば、次の正規表現では、f
またはht
で始まり、次にtp
、オプションでそれに続くs
、最後にコロン(:
)で終わる文字列に一致します。
(f|ht)tps?:
前述の例でのメタキャラクタ(演算子とも言います)はカッコ、パイプ記号(|
)、疑問符(?
)です。文字リテラルは、f
、ht
、tp
、s
およびコロン(:
)です。
カッコは複数のパターン要素を1つの要素にグループ化します。パイプ記号(|
)は両側の要素であるf
とht
の間での選択を示します。疑問符(?
)は、直前の要素であるs
がオプションであることを示します。したがって、前述の正規表現は次の文字列に一致します。
http:
https:
ftp:
ftps:
正規表現は、PERLやJavaのようなプログラミング言語の強力なテキスト処理コンポーネントです。たとえば、PERLスクリプトでは、ディレクトリ内の各HTMLファイルの内容を1つの文字列変数に読み取り、正規表現を使用して文字列内のURLを検索できます。多くのアプリケーション開発者がPERLを使用する理由の1つは、この堅牢なパターン・マッチング機能にあります。
Oracle SQLは正規表現をサポートしているため、開発者はデータベースに複雑なパターン一致ロジックを実装できます。この手法は、次のような理由で有用です。
パターン一致ロジックをデータベース内に集中化させることで、中間層アプリケーションがSQL結果セットの文字列処理に集中するのを回避できます。
たとえば、ライフサイエンス分野のユーザーは、通常、DNAとタンパク質の大規模データベースに格納されている生命情報データのパターン分析にPERLを使用しています。従来、[AG]
.{4}GK[ST]
のようなタンパク質配列の一致検索は中間層で処理されていました。SQL正規表現機能は、処理ロジックをデータに近づけることで、より有効なソリューションを提供します。
サーバー側の正規表現を使用して制約を規定すると、検証ロジックを複数のクライアントで複製するのを回避できます。
Oracle SQLは、表8-1で概要を示すパターン一致条件およびファンクションの正規表現をサポートします。各パターン・マッチャーは指定したパターン(正規表現を使用して記述)を含む文字列を検索し、そこでは表8-2に示すパターン一致オプションが指定されます。関数には追加のオプション(パターンを含む文字列の検索開始位置など)があります。詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
表8-1 Oracle SQLパターン一致条件および関数
名前 | 説明 |
---|---|
条件を問合せの 例: 次の WHERE REGEXP_LIKE((hr.employees.first_name, '^Ste(v|ph)en$') |
|
関数では、指定した文字列での特定パターンの出現回数が戻されます。 例: 次の関数呼出しでは、文字列 REGEXP_COUNT('Albert Einstein', 'e', 7, 'c') ( |
|
関数では、指定した文字列での特定パターンの開始位置を示す整数が戻されます。または、パターンの直後の位置を示す整数を戻すこともできます。 例: 次の関数呼出しでは、 REGEXP_INSTR(hr.employees.email, '\w+@\w+(\.\w+)+') 戻された値がゼロよりも大きい場合、列には有効な電子メール・アドレスが含まれています。 |
|
関数では、指定した文字列での特定パターンの出現を、置換文字列で置き換えた結果の文字列を戻します。 例: 次の関数呼び出しでは、 REGEXP_REPLACE(hr.countries.country_name, '(.)', '\1 ') |
|
関数は、 例: 次の関数呼び出しでは、 REGEXP_SUBSTR('Oracle 2010', 'O r a c l e', 1, 1, 'x') |
表8-2に、表8-1の各パターン・マッチャーで使用可能なパターン一致オプションを示します。
表8-2 Oracle SQL パターン一致条件および関数のパターン一致オプション
オプション | 説明 | 例 |
---|---|---|
|
大/小文字区別なしの一致を指定します。 |
次の関数呼び出しでは、3が戻されます。
REGEXP_COUNT('Albert Einstein', 'e', 'i')
|
|
大/小文字区別ありの一致を指定します。 |
次の関数呼び出しでは、2が戻されます。
REGEXP_COUNT('Albert Einstein', 'e', 'c')
|
|
ドット演算子( |
次の関数呼び出しでは、
REGEXP_SUBSTR('a'||CHR(10)||'d', 'a.d', 1, 1, 'n')
|
|
複数行モードを指定します。文字列内の改行文字で行が終了します。文字列に複数の行を含めることができます。 複数行モードはPOSIX演算子の行頭アンカー( |
次の関数呼び出しでは、
REGEXP_SUBSTR('ab'||CHR(10)||'ac', '^a.', 1, 2, 'm')
|
|
検索パターン内の空白文字が無視されます。デフォルトでは、空白文字はそれ自体に一致します。 |
次の関数呼び出しでは、
REGEXP_SUBSTR('abcd', 'a b c d', 1, 1, 'x')
|
Oracle SQLの正規表現の実装は、次の標準に準拠しています。
IEEEのPortable Operating System Interface(POSIX)標準ドラフト1003.2/D11.2
Oracle SQLは、ASCII(英語)データの照合に関してPOSIX標準に定義されている正規表現演算子の構文と一致セマンティクスに正確に準拠しています。POSIX標準のドラフトについては、次のURLを参照してください。
http://pubs.opengroup.org/onlinepubs/007908799/xbd/re.html
詳細は、「Oracle SQL正規表現内のPOSIX演算子」を参照してください。
Oracle SQLでは、正規表現サポートがPOSIX標準を超えて次のように拡張されています。
多言語データの照合機能が拡張されています。
詳細は、8.4.2項「Oracle SQLのPOSIX標準に対する多言語拡張機能」を参照してください。
POSIX標準には含まれていないが競合もしない(文字クラスのショートカットや最短一致修飾子(?
)など)、よく使用されるPERL正規表現演算子をサポートします。
詳細は、8.4.3項「Oracle SQLのPOSIX標準に対するPERLの影響を受ける拡張機能」を参照してください。
Oracle SQLは正規表現内で一連の共通演算子(メタキャラクタから構成)をサポートします。
注意: メタキャラクタの解析は、正規表現をサポートするツールによって異なります。別の環境からOracle Databaseへ正規表現を移植する場合は、Oracle SQLにより正規表現の構文がサポートされ、予想どおりに解析されることを確認してください。 |
内容は次のとおりです。
表8-3に、POSIX標準拡張正規表現(ERE)構文に定義されたPOSIX演算子の概要を示します。Oracle SQLはASCII(英語)データの照合に関し、POSIX標準に定義されたこれらの演算子の構文と一致セマンティクスに完全に準拠します。Oracle SQLとPOSIX標準でアクションが異なる場合は「説明」列に示されています。
表8-3 Oracle SQL正規表現内のPOSIX演算子
演算子構文 | 名前 | 説明 | 例 |
---|---|---|---|
|
任意の文字 ドット |
データベース・キャラクタ・セットの任意の1文字に一致します。 Linux、UNIXおよびWindowsプラットフォームでは、改行文字はラインフィード文字( Macintoshプラットフォームでは、改行文字はキャリッジ・リターン文字( 注意: POSIX標準では、この演算子はNULLおよび改行文字以外の任意の英字に一致します。 |
正規表現 |
|
1つ以上 プラス数量子 |
直前の部分正規表現の1回以上の出現に一致します(最長一致脚注1)。 |
正規表現 |
|
ゼロ以上 星型数量子 |
直前の部分正規表現のゼロ回以上の出現に一致します(最長一致脚注1)。 |
正規表現 |
|
ゼロまたは1つ 疑問符数量子 |
直前の部分正規表現のゼロまたは1回の出現に一致します(最長一致脚注1)。 |
正規表現 |
|
繰返し 特定数 |
直前の部分正規表現の |
正規表現 |
|
繰返し 最小数 |
直前の部分正規表現の |
正規表現 |
|
繰返し 個数範囲 |
直前の部分正規表現の |
正規表現 |
|
一致文字リスト |
カッコで囲まれたリスト内の任意の1文字に一致します。リスト内では、次の演算子を除くすべての演算子はリテラルとして処理されます。
ハイフン( 注意: POSIX標準では、範囲には現行ロケールの言語定義による範囲の開始から終了までの照合要素がすべて含まれます。したがって、範囲はバイト値の範囲ではなく言語によるもので、範囲正規表現のセマンティクスはキャラクタ・セットに依存しません。Oracle Databaseでは、言語範囲は |
正規表現 |
|
非一致文字リスト |
カッコで囲まれたリストにない任意の1文字に一致します。 文字リストの演算子と範囲については、一致文字リストの演算子の説明を参照してください。 |
正規表現 正規表現 |
|
または |
代替項目のいずれかを一致させます。 |
正規表現 |
|
部分正規表現 グループ化 |
カッコ内の正規表現が1単位として処理されます。部分正規表現は、文字列または演算子を含む複雑な正規表現にすることができます。 後方参照の部分正規表現を参照してください。 |
正規表現 |
|
後方参照 |
直前のn番目の部分正規表現に一致します。 後方参照では、事前に実際の文字列がわからなくても、繰返し文字列を検索できます。
|
正規表現 正規表現 |
|
エスケープ文字 |
後続の文字がリテラルとして処理されます。 円記号(\)を使用すると、通常はメタキャラクタとして処理される1文字を検索できます。二重円記号( |
正規表現 |
|
行頭アンカー |
デフォルト・モード: 文字列の先頭に一致します。 複数行モード:脚注2 ソース文字列の任意の行の先頭に一致します。 |
正規表現 |
|
行末アンカー |
デフォルト・モード: 文字列の末尾に一致します。 複数行モード:脚注2 ソース文字列の任意の行の末尾に一致します。 |
正規表現 |
|
POSIX文字クラス |
指定したPOSIX文字クラスに属する任意の文字(大文字、数字、句読点文字など)に一致します。 注意: 英語による正規表現の場合、範囲正規表現は通常は文字クラスを示します。たとえば、 |
正規表現 |
|
POSIX照合要素演算子 |
現在のロケールに定義された照合要素を指定します。 この構文を使用すると、他の方法では1文字しか許可されない場合にマルチキャラクタ照合要素を使用できます。たとえば、照合要素 |
正規表現 正規表現 |
|
POSIX文字等価クラス |
現行のロケールで指定された文字と同じPOSIX文字等価クラスに属するすべての文字に一致します。 この構文は文字リスト内に含まれる必要があるため、必ず文字リスト用の大カッコ内にネストされます。 文字等価はデータベース・ロケールに対する標準ルールの定義によって異なります。詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。 |
正規表現 |
脚注1最長一致演算子は、照合が続くかぎり、できるだけ多くの出現に一致します。演算子を最短一致にするには、最短一致修飾子(?
)を後に付けます(表8-5を参照)。
脚注2パターン一致オプションm
で複数行モードを指定します(表8-2を参照)。
Oracle SQLのPOSIX演算子を多言語データに適用すると、POSIX標準に指定されている照合機能の範囲を超えて拡張されます。
表8-4に、各POSIX演算子に対し、POSIX標準で演算子の構文が定義されているか、Oracle SQLにより演算子のセマンティクスが多言語データの処理用に拡張されるかどうかを示します。POSIX標準は基本正規表現(BRE)および拡張正規表現(ERE)です。
表8-4 POSIX演算子と多言語演算子の関係
演算子 | POSIX BRE構文 | POSIX ERE構文 | 多言語拡張機能 |
---|---|---|---|
|
あり |
あり |
-- |
|
あり |
あり |
-- |
|
-- |
あり |
-- |
|
-- |
あり |
-- |
|
-- |
あり |
-- |
|
あり |
あり |
あり |
|
あり |
あり |
あり |
|
あり |
あり |
あり |
|
あり |
あり |
あり |
|
あり |
あり |
-- |
|
あり |
あり |
-- |
|
あり |
あり |
-- |
|
あり |
あり |
-- |
|
あり |
あり |
あり |
|
あり |
あり |
あり |
|
あり |
あり |
あり |
|
あり |
あり |
あり |
多言語データにはマルチバイト・キャラクタが含まれている可能性があります。Oracle Databaseでは、直接入力方法でマルチバイト・キャラクタを直接入力するか、関数を使用してマルチバイト・キャラクタを構成できます。\
xxxx
形式のUnicode 16進エンコーディング値は使用できません。Oracle Databaseでは、文字はグラフィカル表現ではなくエンコーディングに使用されるバイト値に基づいて評価されます。
Oracle SQLは、POSIX標準には含まれていないが競合もしない、よく使用されるPERL正規表現演算子をサポートします。
表8-5に、Oracle SQLがサポートするPERLの影響を受ける演算子の概要を示します。
注意: PERLの文字クラス・マッチングはオペレーティング・システムのロケール・モデルに基づいていますが、Oracle SQLの正規表現はデータベースの言語固有のデータに基づいています。通常、ロケール・データを含む正規表現の場合、PERLとOracle SQLで同じ結果が生成されることは期待できません。 |
表8-5 Oracle SQL正規表現でPERLの影響を受ける演算子
演算子構文 | 説明 | 例 |
---|---|---|
|
数字1文字に一致します。 POSIX正規表現 |
正規表現 |
|
数字以外の1文字に一致します。 POSIX正規表現 |
正規表現 |
|
1文字(英数字またはアンダースコア( POSIX正規表現 |
正規表現 |
|
英数字およびアンダースコア以外の1文字に一致します。 POSIX正規表現 |
正規表現 |
|
空白文字1文字に一致します。 POSIX正規表現 |
正規表現 |
|
空白以外の1文字に一致します。 POSIX正規表現 |
正規表現 |
|
単一行モードまたは複数行モードのいずれでも、文字列の先頭に一致します。 POSIX演算子 |
正規表現 |
|
単一行モードまたは複数行モードのいずれでも、文字列の最後に一致します。 POSIX演算子 |
正規表現 |
|
単一行モードまたは複数行モードのいずれでも、文字列の最後に一致します。 POSIX演算子 |
正規表現 |
|
直前の部分正規表現の1回以上の出現に一致します(最短一致脚注1)。 |
正規表現 |
|
直前の部分正規表現のゼロ回以上の出現に一致します(最短一致脚注1)。可能なかぎり空の文字列に一致します。 |
正規表現 |
|
直前の部分正規表現のゼロまたは1回の出現に一致します(最短一致脚注1)。可能なかぎり空の文字列に一致します。 |
正規表現 |
|
直前の部分正規表現の |
正規表現 正規表現 |
|
直前の部分正規表現の |
正規表現 |
|
直前の部分正規表現の |
正規表現 |
脚注1最短一致演算子は、照合が続くかぎり、できるだけ少ない出現に一致します。演算子を最長一致にするには、最短一致修飾子(?
)を省略します。
正規表現は、制約を規定する際に役立つ方法です。たとえば、データベースに標準書式で電話番号を入力する必要があるとします。例8-1では、contacts
表を作成し、p_number
列にCHECK
制約を追加して次の書式モデルを規定しています。
(XXX) XXX-XXXX
例8-1 正規表現を使用した電話番号書式の規定
DROP TABLE contacts; CREATE TABLE contacts ( l_name VARCHAR2(30), p_number VARCHAR2(30) CONSTRAINT c_contacts_pnf CHECK (REGEXP_LIKE (p_number, '^\(\d{3}\) \d{3}-\d{4}$')) );
表8-6に、この正規表現の要素を示します。
表8-6 例8-1の正規表現要素の説明
正規表現要素 | 一致 |
---|---|
|
文字列の先頭。 |
|
左カッコ。円記号( |
|
数字3文字。 |
|
右カッコ。円記号( |
空白文字 |
空白文字。 |
|
数字3文字。 |
|
ハイフン。 |
|
数字4文字。 |
|
文字列の終わり。 |
例8-2に、電話番号をcontacts
表に挿入する正しい文および誤った文を示します。
例8-2 正しい書式と誤った書式での電話番号の挿入
正しい書式は次のとおりです。
INSERT INTO contacts (p_number) VALUES('(650) 555-0100'); INSERT INTO contacts (p_number) VALUES('(215) 555-0100');
次のコードは、CHECK
制約エラーを生成します。
INSERT INTO contacts (p_number) VALUES('650 555-0100'); INSERT INTO contacts (p_number) VALUES('650 555 0100'); INSERT INTO contacts (p_number) VALUES('650-555-0100'); INSERT INTO contacts (p_number) VALUES('(650)555-0100'); INSERT INTO contacts (p_number) VALUES(' (650) 555-0100');
後方参照(表8-3を参照)では参照する部分正規表現が一時バッファに格納されます。そのため後方参照を使用して文字を再配置できます(例8-3を参照)。例8-3の正規表現の要素の説明は、表8-7を参照してください。
例8-3 後方参照を使用した文字の再配置
表を作成して、様々な書式の氏名を移入します。
DROP TABLE famous_people; CREATE TABLE famous_people (names VARCHAR2(20)); INSERT INTO famous_people (names) VALUES ('John Quincy Adams'); INSERT INTO famous_people (names) VALUES ('Harry S. Truman'); INSERT INTO famous_people (names) VALUES ('John Adams'); INSERT INTO famous_people (names) VALUES (' John Quincy Adams'); INSERT INTO famous_people (names) VALUES ('John_Quincy_Adams');
SQL*Plus書式設定コマンド:
COLUMN "names after regexp" FORMAT A20
書式が「ファースト・ネーム、ミドル・ネーム、ラスト・ネーム」の表の各氏名に後方参照を使用して文字を再配置し、書式が「ラスト・ネーム、ファースト・ネーム、ミドル・ネーム」になるようにします。
SELECT names "names", REGEXP_REPLACE(names, '^(\S+)\s(\S+)\s(\S+)$', '\3, \1 \2') AS "names after regexp" FROM famous_people ORDER BY "names";
結果:
names names after regexp -------------------- -------------------- John Quincy Adams John Quincy Adams Harry S. Truman Truman, Harry S. John Adams John Adams John Quincy Adams Adams, John Quincy John_Quincy_Adams John_Quincy_Adams 5 rows selected.
表8-7に、この正規表現の要素を示します。
表8-7 例8-3の正規表現要素の説明
正規表現要素 | 説明 |
---|---|
|
文字列の先頭に一致します。 |
|
文字列の終わりに一致します。 |
|
空白以外の1文字以上に一致します。カッコはエスケープされていないため、グループ化表現として機能します。 |
|
空白文字1文字に一致します。 |
|
最初の部分正規表現、つまり、一致パターンに含まれるカッコの第1グループを置き換えます。 |
|
第2の部分正規表現、つまり、一致パターンに含まれるカッコの第2グループを置き換えます。 |
|
第3の部分正規表現、つまり、一致パターンに含まれるカッコの第3グループを置き換えます。 |
|
カンマを挿入します。 |