パターンマッチングで比較(GLOB句)

広告

条件式の中でカラムの値を文字列と一致するかどうか比較する場合、LIKE句とは異なるGLOB句を使用する方法も用意されています。ここではGLOB句を使ったパターンマッチングを行う方法について解説します。(LIKE句については「パターンマッチングで比較(LIKE句)」を参照して下さい)。

1.GLOB句の使い方
2.特殊文字のエスケープ方法

GLOB句を使用する場合の書式は次の通りです。

SELECT カラム名 , ... FROM テーブル名 WHERE カラム GLOB パターン;

LIKE句との違いはパターンを記述する時に使用する特殊文字です。GLOG句では次のような特殊文字を使ってパターンを記述します。

*      任意の0文字以上の文字列
?      任意の1文字
[abc]  a or b or cのいずれかに一致
[a-d]  aからdまでにいずれかに一致

'*'は0文字以上の任意の文字列にマッチします。例えばパターンとして「a*b」が記述されていた場合、「a」で始まり0個以上の任意の文字が間に入り最後に「b」で終わるような次の文字列にマッチします。

ab
axb
aonb
aoneb
atreeb

'?'は任意の1文字にマッチします。例えばパターンとして「a?b」が記述されていた場合、「a」で始まり1つの任意の文字が間に入り最後に「b」で終わるような次の文字列にマッチします。

axb
aob
agb

'[abc]'は括弧内のいずれかの文字にマッチします。例えばパターンとして「[mk]*」が記述されていた場合、「m」又は「k」で始まり任意の長さの文字列にマッチします。なお「[^mk]*」のように先頭に「^」を付けると括弧内のいずれの文字にも一致しない文字にマッチします。

mouse
kitchen

括弧内では「-」を使って'[a-d]'のように範囲指定もできます。この場合は括弧内の最初の文字から最後の文字までにある全ての文字にマッチします。例えばパターンとして「[a-zA-Z0-9]*」が記述されていた場合、「a」から「z」または「A」から「Z」または「0」から「9」までの文字で始まる任意の長さの文字列にマッチします。

Hello
2014year
なおLIKE句と異なりGLOB句では大文字と小文字を区別します。またGLOB句ではLIKE句と異なりESCAPE句を使用することはできません。

それでは実際に試してみます。次のようなテーブルを作成しました。

create table user(id integer, nickname text);

p12-1

いくつかのデータが格納されています。取得するデータの条件を指定しないでデータを取得した場合は次のようになります。

select * from user;

p12-2

それではGLOB句を使ってパターンマッチングを行ってみます。次の例では「nickname」カラムの値が「'b*'」とマッチするデータを取得しています。('b'で始まる文字列とマッチします)。

select * from user where nickname glob 'b*';

p12-3

GLOB句の場合は大文字と小文字を区別しますので'b'または'B'で始まる文字列とマッチさせたい場合は次のようにパターンを記述します。

select * from user where nickname glob '[bB]*';

p12-4

次の例では「nickname」カラムの値が「'[a-z]*'」とマッチするデータを取得しています。(アルファベットの小文字で始まる文字列とマッチします)。

select * from user where nickname glob '[a-z]*';

p12-5

このようにGLOB句を利用することで任意のパターンを定義してそのパターンに一致するデータを取得することができます。

GLOB句の中で'*'、'?'、'['、']'の4つの文字は特別な意味を持ちますが、特殊な文字ではなく文字の一つとしてこの4つの文字を使用したい場合にはエスケープ処理をする必要があります。GLOB句では特殊な文字をエスケープしたい場合には[]で囲い'[*]'や'[[]'のように記述します。

それでは実際に試してみます。先ほどと同じテーブルを使用し、取得するデータの条件を指定しないでデータを取得した場合は次のようになります。

select * from user;

p12-6

「nickname」カラムの値に「'?'」が含まれているデータを取得します。エスケープを行わずに次のように記述してしまうと「1文字以上の文字が含まれる文字列」というパターンになってしまうので期待した結果にはなりません。(全てのデータがマッチしてしまう)。

select * from user where nickname glob '*?*';

p12-7

エスケープを行い次のようなパターンを記述すれば期待した結果が取得できます。

select * from user where nickname glob '*[?]*';

p12-8

なおLIKE句とは異なりGLOB句では特殊文字をエスケープする方法は選択できません。

( Written by Tatsuo Ikura )