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

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

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

この記事の信頼性

この記事は、Youtubeにて日本最大級のプログラミング教育のチャンネルを運営しているキノコードが執筆、監修しています。
私自身は、2012年からプログラミング学習を始め、2019年以降はプログラミング教育に携わってきた専門家です。
他にも、私には下記のような実績や専門性があります。

  • キノコードは毎月10名以上、合計100名以上ののプログラミング学習者と1対1でお悩みを聞き、アドバイスをしています
  • キノコード自身は、プログラミングスクールに通ったり、本や有料åの動画で勉強してきた経験もあります
  • キノコードは、プログラミング学習サービス「キノクエスト」を運営しています
  • 本の出版、プログラミング雑誌への寄稿の実績があります

プログラミング学習サービス「キノクエスト」のご紹介

キノコードでは、プログラミングを習得するためのプログラミング学習サービス「キノクエスト」を運営しています。
Pythonの問題の他に、SQLの問題も120問以上あります。
キノクエストには、学習カリキュラムがあり、学習順番に悩むことなく学習を進められます。
月額1,990円と本1冊分の値段です。

キノクエストの特徴は下記の通りです。

  • SQLの問題も120問以上
  • プログラミング学習をしている仲間が集まるコミュニティがある
  • 1000問以上の問題を解いてプログラミングを習得
  • 環境構築不要ですぐに始められる
  • 動画と連動しているので、インプットもできる。
  • 月額1,990円で、コミュニティもセット

キノクエストを詳しく知りたい方は、紹介ページをご覧ください。

▼キノクエストの紹介ページはこちら▼
https://kino-code.com/kq_service_a/

それでは、レッスンスタートです。

正規表現とは

正規表現は、データの中から「aから始まる文字列」や「a,b,cのいずれかを含む文字列」といったように、特定のパターンにマッチするものを見つける時などに使われる手法のことです。
正規表現とは「文字列の集合を一つの文字列で表現する方法」といえます。

正規表現は、regular expressionの訳です。正則表現、正則式、正規式とも呼ばれることもあります。
プログラミングにおける正規表現は、そもそもの語源からは拡張されて使われています。
そのため、現在では、正規表現という名前は実態に即していないとも言われています。

したがって、正規表現と聞けば、パターンマッチング行う機能と考えればよいでしょう。

正規表現の種類と書き方

さて、ここでは最初に基本的なSQLの正規表現について、順に解説していきます。

いずれかに一致

正規表現 説明 書き方 マッチ例
[...] カッコ内のいずれか1文字 [abc] a,b,c
[^...] カッコ内の文字以外 [^abc] a,b,c以外
| |の左右いずれか a|bc a
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がマッチすることになります。

文字列の先頭・末尾

正規表現 説明 書き方 マッチ例
^ 直後の文字が文字列の先頭 ^ab ab
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のレコードのみを、正しく抽出することができました。

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

レッスンは以上です。

キノコードでは、プログラミングを習得するためのプログラミング学習サービス「キノクエスト」を運営しています。
Pythonの問題の他に、SQLの問題も120問以上あります。
キノクエストには、学習カリキュラムがあり、学習順番に悩むことなく学習を進められます。
月額1,990円と本1冊分の値段です。

キノクエストの特徴は下記の通りです。

  • SQLの問題も120問以上
  • プログラミング学習をしている仲間が集まるコミュニティがある
  • 1000問以上の問題を解いてプログラミングを習得
  • 環境構築不要ですぐに始められる
  • 動画と連動しているので、インプットもできる。
  • 月額1,990円で、コミュニティもセット

キノクエストを詳しく知りたい方は、紹介ページをご覧ください。

▼キノクエストの紹介ページはこちら▼
https://kino-code.com/kq_service_a/