【SQL超入門講座】19.正規表現|複雑なパターンマッチングを条件に抽出する方法

正規表現とは

こんにちはキノコードです。
以前のレッスンで解説した、LIKE演算子によるパターンマッチングを覚えているでしょうか。
LIKE演算子によるパターンマッチングでは、ワイルドカードの_と%を使用してパターンを表記しました。

今回のレッスンでは、より複雑なパターンを表記できるようになるため、正規表現の使い方を解説します。
正規表現の理解は、SQLだけでなくプログラミングを行う上でとても重要です。
様々な記号を使用するので、最初からすべてを覚えるのは大変ですが、少しずつ使いこなせるようになりましょう。
それではレッスンスタートです。

【SQL超入門講座】19.正規表現|複雑なパターンマッチングを条件に抽出する方法

正規表現の種類と書き方

最初に基本的な正規表現について、順に解説していきます。

いずれかに一致

正規表現説明書き方マッチ例
[...]カッコ内のいずれか1文字[abc]a,b,c
[^...]カッコ内の文字以外[^abc]a,b,c以外
||の左右いずれかa|bca
bc
()()内の文字をグループ化a(b|bc)ab
abc

それでは指定した文字のいずれかに一致することを表記する方法を見ていきましょう。
[...](角括弧の中に文字列)と書くと、[]の中のいずれかの文字に一致することを表します。
例えば[abc](角括弧の中にabc)と書けば、a、b、cのいずれかがマッチすることになります。
一方で[^...](角括弧の中の文字列の前に、キャレットをつけると)と^を文字の前につけると、[]の中の文字以外という意味になります。
そのため[^abc](角括弧の中にキャレットabc)と書けばa、b、c以外の1文字がマッチすることになります。

|(パイプライン)は文字列が|(パイプライン)の左右のいずれかに一致することを表します。
例えばa|bcと書けば、a、bcのどちらかがマッチします。
また()(丸括弧)を用いることで、文字列をグループとして扱うことができます。
今学んだ|を用いてa(b|bc)(a丸括弧、更にその中にbパイプラインbc)と書けば、()の中はbかbcのどちらかに一致することを表しているので、abとabcがマッチすることになります。

文字列の先頭・末尾

正規表現説明書き方マッチ例
^直後の文字が文字列の先頭^abab
abc
$直前の文字が文字列の末尾bc$bc
abc

次に文字列の先頭と末尾を表す^と$について見ていきましょう。
^は直後の文字が文字列の先頭であることを表します。
つまり^abと書けば、ab、abcなどの文字列がマッチします。
一方$は直前の文字が文字列の末尾であることを表します。
そのためbc$と書けば、bc、abcなどの文字列がマッチすることになります。

文字の繰り返し(0回、1回以上)

正規表現説明書き方マッチ例
.任意の1文字.任意の1文字
*直前の文字を0回以上繰り返す.*0文字以上の任意の文字列
+直前の文字を1回以上繰り返す.+1文字以上の任意の文字列
?直前の文字が0回か1回a?bc
abc

ここからは文字の繰り返しを表す正規表現について確認していきます。
は直前の文字を0回以上繰り返すことを表し、+は1回以上繰り返すことを表します。
正規表現では、.は任意の1文字を表します。
そのため.
と書けば任意の0文字以上の文字列を、.+と書けば任意の1文字以上の文字列を表記することができます。

?は直前の文字が0回か1回出現することを表します。
*、+との違いは、直前の文字の複数回の繰り返しではなく、直前の文字の出現回数が0回か1回と決まっていることです。
そのためa?と書けば、abc、bcなどがマッチし、aabcなどaを2回以上繰り返している文字列はマッチしないことになります。

文字の繰り返し(n回)

正規表現説明書き方マッチ例
{n}直前の文字をn回繰り返すa{3}aaa
{n,}直前の文字をn回以上繰り返すa{3,}aaabc
aaaaabc
{,m}直前の文字をm回以下繰り返すa{3,}aabc
aaabc
{n,m}直前の文字をn以上m回以下繰り返すa{3,4}aaabc
aaaabc

先ほど学んだ*、+は、それぞれ直前の文字を0回以上、1回以上繰り返すことを意味しました。
これに対し{n}(波括弧の中に自然数nを書くと)は直前の文字をn回繰り返すことを表すことができます。

また繰り返しの回数を示す自然数の後に,をつけて{n,}と書けば、直前の文字をn回以上繰り返す文字列を表すことができます。
これに対し、カンマの位置を自然数の前につけて{,m}と書けば、直前の文字をn回以下繰り返す文字列を表すことができます。
さらにこれらを合体して、{n,m}と書けば直前の文字をn回以上、m回以下繰り返している文字列だけがマッチします。
例えば、a{3,4}と書けば、aaabc、aaaabcといったaを3回以上、4回以下繰り返している文字列だけがマッチすることになります。

SQLでの使用例

最後にこれまでに学んだ正規表現のいくつかを使って、test_tableからデータを抽出してみましょう。
test_tableは、このようなカラムからなる、どの社員がいつ何を売上げたかを記録しているテーブルです。

それでは社員IDがaで始まり、03もしくは52で終わるレコードだけを抽出します。
SQLは次のように書くことができます。

SELECT  FROM test_table
WHERE 社員ID ~ '^a.
(03|52)

PostgreSQLで正規表現を使用する際は、~(チルダ)を用います。
WHERE句でパターンマッチングを行うカラムの社員IDの後にチルダを書き、それに続いて正規表現を書いていきます。

まず、先頭の文字がaであること^を用いて、^aと書きます。
続いて、先頭と末尾以外はどんな文字列でもよいので、任意の0文字以上の文字列を表す.*を書きます。
最後に、末尾の文字が03もしくは52であることを$を用いて書きます。
これは記号の左右いずれかが一致することを表す|と、文字をグループ化する()を併用して、 (03|52)$と書くことができます。
これで「aで始まり、03もしくは52で終わる」文字列を書き表すことができました。

それではSQLを実行します。

条件に合う社員IDのレコードのみを、正しく抽出することができました。

これで基本的な正規表現を一通り確認することができました。
これらの正規表現を組み合わせて使用することであらゆるパターンを表記できます。
最初から全てを覚えることは難しいので、必要に応じて都度確認しながら覚えていくようにしてくださいね。

レッスンは以上です。いかがでしたでしょうか。
キノコードでは分かりやすく飽きない動画づくりを意識しています。
今後はこのようなレッスン動画を予定しています。
レッスンの新着通知が行きますので、是非チャンネル登録をお願いします。
それではまた、次の動画でお会いしましょう。

PostgreSQLで正規表現を使用する際は、~(チルダ)を用います。
WHERE句でパターンマッチングを行うカラムの社員IDの後にチルダを書き、それに続いて正規表現を書いていきます。

まず、先頭の文字がaであること^を用いて、^aと書きます。
続いて、先頭と末尾以外はどんな文字列でもよいので、任意の0文字以上の文字列を表す.*を書きます。
最後に、末尾の文字が03もしくは52であることを$を用いて書きます。
これは記号の左右いずれかが一致することを表す|と、文字をグループ化する()を併用して、 (03|52)$と書くことができます。
これで「aで始まり、03もしくは52で終わる」文字列を書き表すことができました。

それではSQLを実行します。

条件に合う社員IDのレコードのみを、正しく抽出することができました。

これで基本的な正規表現を一通り確認することができました。
これらの正規表現を組み合わせて使用することであらゆるパターンを表記できます。
最初から全てを覚えることは難しいので、必要に応じて都度確認しながら覚えていくようにしてくださいね。

レッスンは以上です。いかがでしたでしょうか。
キノコードでは分かりやすく飽きない動画づくりを意識しています。
今後はこのようなレッスン動画を予定しています。
レッスンの新着通知が行きますので、是非チャンネル登録をお願いします。
それではまた、次の動画でお会いしましょう。