MySQL正規表現での先読みおよび先読みの使用 (2024/07/30)

MySQL正規表現での先読みおよび先読みの使用 (2024/07/30)

https://blogs.oracle.com/mysql/post/using-lookahead-lookbehind-in-mysql-regular-expressions

投稿者: Scott Stroz | MySQL Developer Advocate


正規表現は強力ですが、開発者向けの誤解が多いツールです。最近の投稿では、部分正規表現後方参照(特殊なタイプの部分正規表現)について説明しました。この記事では、他の2つの特殊部分式の例を示します: 先を見て後ろを見てください。



要件


これまでに使用したものと同じデータを使用して、その単語がipsumからスペースで区切られたときに、テキストipsumの前にある単語だけを返す必要があります。ここでのキッカーは、テキストipsumはパターン一致の一部である必要がありますが、返さないことです。この要件は難しく聞こえるかもしれませんが、先読みパターン・マッチングを使用すると非常に簡単です。



先読み?


一言で言えば、先読みは、一致するが戻されないパターンを定義します。先読み一致は、特殊なタイプの部分式であり、そのように書式設定されます。先読みの構文は、( )を使用して、マッチングするテキストの前に?= が付いた部分式です。



ソリューション


例を見れば、構文を理解しやすくなる場合があります。ここに私達の条件を満たす解決があります。


select
    id,
    name,
    regexp_substr(sample, '[^ ]+(?=[ ]+ipsum)') `snippet`
from ipsum
where regexp_like(sample, '[^ ]+(?=[ ]+ipsum)')


使用する正規表現は[^ ]+(?=[ ]+ipsum)です。これを分解して、人間が読める用語にしましょう。


  • [^ ]+ - 正規表現の最初の部分は、空白以外の1つ以上の文字が必要であることを示す文字セットです。
  • +は、先行する1つ以上の文字または文字セットが必要であることを示します。
  • ( - 左カッコが部分式を開始します。
  • ?= - 部分式の最初の部分は、先読みを使用していることを示します。
  • [ ]+ - この文字セットは、出力一致パターンが1つ以上の空白で始まる必要があることを示します。
  • +は、先行する1つ以上の文字または文字セットが必要であることを示します。
  • ipsum - このテキストは、リテラル・テキストipsumと一致させることを示します。
  • ) - 右カッコでサブ式が終了します。


これを英語にすると、このパターンは、空白以外の1つ以上の文字、その後に1つ以上のスペース、その後にテキストipsumを付ける必要があります。これは照合するパターンですが、返される部分は先読み以外のパターンで、スペース以外の1つ以上の文字です。


この問合せの結果は、次のようになります。


+----+--------------+---------+
| id | name         | snippet |
+----+--------------+---------+
|  1 | Lorem Ipsum  | Lorem   |
|  2 | Zombie Ipsum | Zombie  |
|  5 | Space Ipsum  | strife  |
|  6 | Cat Ipsum    | Cat     |
|  8 | Pirate Ipsum | ensign  |
| 10 | Dog Ipsum    | Doggo   |
| 11 | Pizza Ipsum  | Pizza   |
| 14 | Hacker Ipsum | Haxx0r  |
| 15 | 90's Ipsum   | bagels  |
+----+--------------+---------+
9 rows in set (0.0064 sec)


9行は私たちのパターンに一致し、regexp_substr()への呼び出しから返されるものが、各サンプルのipsumの前にある単語です。



外観


前述のとおり、先読みは、パターンの別の部分に続くパターンと一致する特殊な部分式です。しかし、わたしたち が わたしたち の 全体 的 な パターン の 前 に ある パターン を 一致 さ せ たい と し たら、どう なる でしょ う か。そのため、後方から見ることができます。構文は多少異なります(?= ではなく?<=)。ただし、結果は同じです。ルックビハインドはパターンの照合に使用されますが、一致の一部としては返されません。



新規要件


新しい要求が与えられた。ここで、テキストipsumのあとに続く単語を返す必要がありますが、空白で区切られた場合にのみ返されます。


次に、この新しい要件を満たす問合せを示します。


select
    id,
    name,
    regexp_substr(sample, '(?<=ipsum[ ])[^ ]+') `snippet`
from ipsum
where regexp_like(sample, '(?<=ipsum[ ])[^ ]+')


正規表現(?<=ipsum[ ])[^ ]+を分解します。


  • ( - 左カッコが部分式を開始します。
  • ?= - 部分正規表現の最初の部分は、ルックビハインドを使用していることを示します。
  • ipsum - このテキストは、リテラル・テキストipsumと一致させることを示します。
  • [ ] - この文字セットは、一致パターンが1つのスペースで終わる必要があることを示します。
  • ) - 右カッコでサブ式が終了します。
  • [^ ]+ - 正規表現の最後の部分は、空白以外の1つ以上の文字が必要であることを示す文字セットです。
  • +は、先行する1つ以上の文字または文字セットが必要であることを示します。


プレーン言語での入力: テキストipsumのあとに1つのスペース、その後にスペース以外の1つ以上の文字を照合します。Lookbehindを使用するため、テキストipsumとipsumの後のスペースは一致しますが、返されません。この問合せの結果は次のようになります。


+----+--------------+----------+
| id | name         | snippet  |
+----+--------------+----------+
|  1 | Lorem Ipsum  | dolor    |
|  2 | Zombie Ipsum | reversus |
|  6 | Cat Ipsum    | dolor    |
|  8 | Pirate Ipsum | avast    |
| 10 | Dog Ipsum    | thicc    |
| 11 | Pizza Ipsum  | dolor    |
| 13 | Trek Ipsum   | is       |
| 14 | Hacker Ipsum | tunnel   |
| 15 | 90's Ipsum   | moody    |
+----+--------------+----------+
9 rows in set (0.0067 sec)



まとめ


正規表現を使用する場合、lookaheadおよびlookbehindと呼ばれる特殊な部分式を使用して、一致させるが戻らないパターンの一部を定義できます。これらの部分正規表現は、一致させるパターンの前または後に続く文字列内のテキストを検索する場合に便利です。MySQLの正規表現の詳細は、ドキュメントを参照してください。


コメント

このブログの人気の投稿

Oracle RACによるメンテナンスのためのドレインとアプリケーション・コンティニュイティの仕組み (2023/11/01)

Oracle APEXのInteractive Gridで、Oracle Formsと比較して、重複行の検証を制御/通過させる方法 (2022/07/21)

Oracle APEX 24.1の一般提供の発表 (2024/06/17)