MySQL 正規表現(Regexp)
⚡ スマートサマリー
MySQL 正規表現 (REGEXP) は、ワイルドカードでは表現できない柔軟なパターンに対して列の値を照合します。ここでは、REGEXP の構文、RLIKE の同義語、サポートされているすべてのメタ文字、myflixdb データベースに対する修正されたクエリ例、および追加された正規表現関数について説明します。 MySQL 8.0.

何ですか MySQL 正規表現?
MySQL 正規表現 複雑な条件に一致するデータを検索するのに役立ちます。正規表現は、探している値そのものではなく、値の形状を記述するパターンです。
すでに一緒に仕事をしたことがあるなら MySQL ワイルドカードLIKE演算子でも同様の結果が得られるのに、なぜ正規表現を学ぶ価値があるのか疑問に思うかもしれません。その答えは表現力にあります。ワイルドカードは2つの記号しか使用できませんが、正規表現は文字範囲、代替文字、繰り返し、単語の位置などを単一のパターンで記述できます。
目的が明確になったところで、次のセクションでは、すべての正規表現クエリで使用する構文を紹介します。
正規表現の基本構文
正規表現の基本的な構文は以下のとおりです。
SELECT * FROM table_name WHERE fieldname REGEXP 'pattern';
ここ:
- 「SELECT文」 標準です SELECTステートメント.
- 「WHERE フィールド名」 これは、正規表現が適用される列の名前です。
- 「REGEXP 'パターン'」 — REGEXPは正規表現演算子であり、「pattern」は一致させるパターンを表します。 RLIKE REGEXP の同義語 そして同じ結果を返します。LIKE演算子との混同を避けるため、REGEXPを使用することをお勧めします。
それでは、具体的な例を見てみましょう。
SELECT * FROM `movies` WHERE `title` REGEXP 'code';
上記のクエリは、「code」という単語を含むすべての映画タイトルを検索します。「code」がタイトルの先頭、中間、末尾のいずれにあっても構いません。タイトルにこのパターンが含まれていれば、該当する行が返されます。
値の開始位置を文字リストと照合する
タイトルがa、b、c、またはdで始まり、その後に任意の数の文字が続く映画を探したいとします。そのためには、文字リストとキャレットメタ文字を組み合わせます。
SELECT * FROM `movies` WHERE `title` REGEXP '^[abcd]';
上記のスクリプトを実行すると、 MySQL ワークベンチ myflixdbデータベースに対して以下の結果を得ました。
| 映画ID | タイトル | ディレクター | リリース年 | カテゴリ ID |
|---|---|---|---|---|
| 4 | Code 名前はブラック | エドガー・ジムズ | 2010 | NULL |
| 5 | ダディーズ・リトル・ガールズ | NULL | 2007 | 8 |
| 6 | 天使と悪魔 | NULL | 2007 | 6 |
| 7 | ダ・ヴィンチ Code | NULL | 2007 | 6 |
パターン「^[abcd]」では、キャレット(^)は値の先頭から一致を開始することを要求し、文字リスト[abcd]は最初の文字がa、b、c、またはdであるタイトルのみを受け入れます。デフォルトの照合順序では比較は大文字小文字を区別しないため、「Code 「名前 Black」が返されます。
否定文字リストを持つ文字を除外する
それでは、スクリプトを修正して文字リストを否定し、どの行が返されるかを確認してみましょう。
SELECT * FROM `movies` WHERE `title` REGEXP '^[^abcd]';
上記のスクリプトを実行すると、 MySQL myflixdbデータベースに対してWorkbenchを実行すると、以下の結果が得られます。
| 映画ID | タイトル | ディレクター | リリース年 | カテゴリ ID |
|---|---|---|---|---|
| 1 | パイレーツ・オブ・カリビアン 4 | ロブ·マーシャル | 2011 | 1 |
| 2 | サラ・マーシャルを忘れる | ニコラス・ストーラー | 2008 | 2 |
| 3 | X-メン | 2008 | ||
| 9 | Honey moonERS | ジョン・シュルツ | 2005 | 8 |
| 16 | 67% 有罪 | 2012 | ||
| 17 | チャップリンの独裁者 | チャーリー・チャップリー | 1920 | 7 |
| 18 | サンプル動画 | 匿名の | 8 | |
| 19 | 映画3 | ジョン·ブラウン | 1920 | 8 |
文字リスト内では、キャレットの意味が変わります。「^[^abcd]」は引き続き一致箇所を先頭に固定しますが、「[^abcd]」は囲まれた文字のいずれかで始まるすべてのタイトルを除外します。
これら2つの例では、アンカーと文字リストのみを使用しています。次のセクションでは、メタ文字セット全体について説明します。
正規表現メタキャラクター
上記の例は、正規表現の最も単純な形式を示しています。メタ文字を使用すると、パターン検索を微調整できます。メタ文字は、繰り返し、代替、範囲、および位置を表します。以下の表は、サポートされているすべてのメタ文字を一覧にしたものです。 MySQL 正規表現演算子と、それぞれの修正例。
| チャー | 詳細説明 | 例: | |
|---|---|---|---|
| * | その アスタリスク(*) 0 個以上のインスタンスに一致する 一文字 それが先行します。 | SELECT * FROM 映画 WHERE タイトル REGEXP 'da*'; 「d」の後に0個以上の「a」文字が続くパターンに一致するので、Da Vinci Code 「Daddy's Little Girls」も該当します。「a」の文字が必ず含まれている場合は、「da+」を使用してください。 | |
| + | その プラス(+) 直前の文字が1回以上出現するのと一致する。 | SELECT * FROM `映画` WHERE `タイトル` REGEXP 'mon+'; 「mon」の後に「n」の文字が1つ以上続く映画をすべて表示します。例えば、「天使と悪魔」などです。 | |
| ? | その 疑問符(?) 直前の文字と0回または1回一致する。 | SELECT * FROM `カテゴリ` WHERE `カテゴリ名` REGEXP 'com?'; 「co」にオプションで「m」を付けて一致させます。例:comedy(コメディ)とromantic comedy(ロマンティック・コメディ)。 | |
| . | その ドット(.) 改行文字を除く任意の1文字に一致します。 | SELECT * FROM 映画 WHERE `公開年` REGEXP '200.'; 「200」の後に任意の数字が続く年に公開されたすべての映画を表示します。例:2005、2007、2008。 | |
| [ABC] | その 文字一覧 [abc] 囲まれた文字のいずれか1つに一致します。 | SELECT * FROM `映画` WHERE `タイトル` REGEXP '[vwxyz]'; 「vwxyz」に含まれる任意のキャラクターが1人でも含まれている映画をすべて表示します。例えば、X-メンとダ・ヴィンチ Code. | |
| [^ abc] | その 否定リスト [^abc] 囲まれた文字以外の任意の文字に一致します。 | SELECT * FROM `映画` WHERE `タイトル` REGEXP '^[^vwxyz]'; タイトルが「vwxyz」の文字で始まらないすべての映画を返します。 | |
| [AZ] | その 範囲 [AZ] 任意の大文字に一致します。 | SELECT * FROM `members` WHERE `postal_address` REGEXP '[AZ]'; 住所にAからZまでの文字が含まれるすべての会員に通知します。例えば、会員番号1のジャネット・ジョーンズなどです。 | |
| [az] | その 範囲 [方位角] 任意の小文字に一致します。 | SELECT * FROM `members` WHERE `postal_address` REGEXP '[az]'; 住所に「a」から「z」までの文字が含まれるすべての会員を表示します。デフォルトの照合順序は大文字と小文字を区別しないため、この範囲は大文字にも一致することに注意してください。 | |
| [0-9] | その 範囲[0-9] 0から9までの任意の数字に一致します。 | SELECT * FROM `members` WHERE `contact_number` REGEXP '[0-9]'; 連絡先番号に少なくとも1桁の数字が含まれているすべてのメンバーを表示します。たとえば、Robert Phil。 | |
| ^ | その キャレット (^) マッチを値の開始点に固定します。 | SELECT * FROM `映画` WHERE `タイトル` REGEXP '^[cd]'; タイトルが「c」または「d」で始まるすべての映画を表示します。たとえば、 Code 名前ブラック、パパの小さな女の子たち、そしてダ・ヴィンチ Code. | |
| $ | その ドル記号 ($) 値の末尾にマッチを固定します。 | SELECT * FROM `movies` WHERE `title` REGEXP 'code$'; タイトルが「code」で終わるすべての映画を表示します。たとえば、ダヴィンチ Code. | |
| | | その 縦棒 (|) 代替案を分離する。 | SELECT * FROM `映画` WHERE `タイトル` REGEXP '^[cd]|^[u]'; タイトルが「c」、「d」、または「u」で始まるすべての映画を表示します。たとえば、 Code 名前 ブラック、ダ・ヴィンチ Code、そしてアンダーワールド – Awakenる。 | |
| \b | その 単語境界(\b) 単語の先頭または末尾に一致します。これは、古い [[:<:]] および [[:>:]] マーカーに取って代わります。 MySQL 8.0は削除されました。 | SELECT * FROM `movies` WHERE `title` REGEXP '\\bfor'; 「for」で始まる単語を含むすべての映画を表示します。たとえば、「Forgetting Sarah Marshal」などです。 MySQL 5.7 同等のパターンは '[[:<:]]for' です。 | |
| [[:クラス:]] | その キャラクタークラス 指定された文字グループに一致します: [[:alpha:]] は文字、[[:space:]] は空白、[[:punct:]] は句読点、[[:upper:]] は大文字です。 角括弧。 | SELECT * FROM `movies` WHERE `title` REGEXP '^[[:alpha:][:space:]]+$'; タイトルに文字とスペースのみが含まれる映画をすべて表示します。たとえば、「Forgetting Sarah Marshal」は表示されますが、「Pirates of the Caribean 4」は数字が含まれているため除外されます。 | |
バックスラッシュ(\)はエスケープ文字です。 MySQL 文字列を最初に解析し、次にパターンを解析します。リテラルのバックスラッシュは、REGEXP パターン内では二重バックスラッシュ (\\) として記述する必要があります。
⚠️ バージョン警告: MySQL 8.0.4 では、古い正規表現エンジンが ICU ライブラリに置き換えられました。このリリースでは単語マーカー [[:<:]] と [[:>:]] が削除されたため、古い資料からコピーされたパターンは「構文エラー」で失敗します。 MySQL 8.0. 代わりに \b を使用してください。
すべてのメタ文字が定義された今、当然の疑問が生じます。より単純なLIKE演算子をREGEXPに置き換えるべきなのはどのような場合でしょうか?
REGEXPとLIKE:どちらを使うべきか?
どちらの演算子もパターンに基づいて行をフィルタリングしますが、解決する問題は異なります。LIKEは2つの記号しか認識しませんが、REGEXPは上記に示したメタ文字セット全体を認識します。この強力な機能には代償が伴うため、どちらを選ぶかは好みの問題ではなく、トレードオフの問題です。
| 基準 | LIKE | REGEXP |
|---|---|---|
| パターン記号 | % と _ のみ | Anchors、範囲、交替、量指定子、文字クラス |
| 典型的な使用 | 接頭辞、接尾辞、および「含む」検索 | 検証、複数の選択肢、位置認識マッチング |
| インデックスの使用状況 | パターンが%で始まらない場合に可能 | インデックスを一切使用しない |
| 戻り値 | 正しいか間違っているか | 1または0、あるいはどちらかのオペランドがNULLの場合はNULL |
単純なマッチングには、読みやすくインデックスも使用できるLIKEを使用してください。単一のパターンで複数のルールを同時に表現する必要がある場合(例:「cまたはdで始まり、数字で終わる」)は、REGEXPを使用してください。大きなテーブルの場合は、まずインデックス条件を使用して行を絞り込み、その絞り込まれたセットにREGEXPを適用してください。
MySQL 8.0 正規表現関数
REGEXP演算子は、値がパターンに一致するかどうかという1つの質問にのみ答えます。 MySQL 8.0ではさらに進んで、例えば、tract と一致するテキストを書き換えます。それぞれオプションの match_type 引数を受け付け、'c' は大文字小文字を区別する比較を強制し、'i' は大文字小文字を区別しない比較を強制します。
- REGEXP_LIKE(expr, pattern) 値がパターンに一致する場合に 1 を返します。これは REGEXP 演算子の関数形式であり、match_type 引数によって大文字と小文字の区別が明示されます。
- REGEXP_INSTR(expr, pattern) 一致した最初の文字の位置を返します。パターンが見つからない場合は 0 を返します。
- REGEXP_SUBSTR(expr, pattern) 一致する部分文字列自体を返します。これは、長いテキスト値から年、コード、または数値を抽出する場合に便利です。
- REGEXP_REPLACE(expr, pattern, replacement) 一致するすべての値を置き換えて返します。これにより、内部のデータをクリーンアップできます。 SQL UPDATEクエリ.
SELECT title, REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title FROM `movies` WHERE REGEXP_LIKE(title, '[0-9]');
上記のクエリは、数字を含むすべての映画タイトルと、その数字自体を返します。 MySQL 5.7 これらの関数は利用できないため、REGEXP 演算子が唯一の選択肢となります。
