先読みと後読みを使ったパターンの記述
正規表現における先読みと後読みは、マッチするかどうか確認は行うけれどマッチした文字列としては取得しないときに利用します。先読みには肯定先読みと否定先読み、後読みには肯定先読みと否定先読み、がそれぞれ用意されています。ここでは Python を使って正規表現で先読みと後読みを使用する方法について解説します。
(Last modified: )
正規表現における先読みと後読みとは
先読み(肯定先読み、否定先読み)と後読み(肯定後読み、否定後読み)の書式は次の通りです。
パターンA(?=パターンB) 肯定先読み パターンA(?!パターンB) 否定先読み (?<=パターンB)パターンA 肯定後読み (?<!パターンB)パターンA 否定後読み
先読みの場合はパターン A の直後にパターン B が続く場合(または続かない場合)にマッチし、後読みの場合は パターン A の直前にパターン B がある場合(またはない場合)にマッチします。どちらもパターン B も含めてマッチするかどうか判断しますが、マッチした文字列として取得するのはパターン A にマッチした部分だけです。
それでは順に見ていきます。
※ 先読みと後読みが実際にどのように対象の文字列にマッチするのかについて、より詳しくは「正規表現における先読みと後読みを使ったパターン」を参照されてください。
肯定の先読み
肯定の先読みは、対象の文字列がパターン A の直後にパターン B に続く場合にマッチします。この時、マッチした値としてはパターン A にマッチした部分だけを取得します。
パターンA(?=パターンB) 肯定先読み
例えば次のパターンで考えてみます。
r'smart(?=phone)'
smart のあとに phone が続く場合のみマッチします。 smartphone はマッチしますが、 smart や smartwatch はマッチしません。そしてマッチした文字列として取得するのは smart のみです。
簡単なサンプルで試してみます。
import re pattern = re.compile(r'smart(?=phone)') print(bool(pattern.search('smart'))) >> False print(bool(pattern.search('smartphone'))) >> True print(bool(pattern.search('smartwatch'))) >> False result = pattern.search('smartphone') print(result.group(0)) >> smart
否定の先読み
否定の先読みは、対象の文字列がパターン A の直後にパターン B が続かない場合にマッチします。この時、マッチした値としてはパターン A にマッチした部分だけを取得します。
パターンA(?!パターンB) 否定先読み
例えば次のパターンで考えてみます。
r'smart(?!phone)'
smart のあとに phone が続かない場合のみマッチします。 smartphone にはマッチしませんが、 smart や smartwatch はマッチします。そしてマッチした文字列として取得するのは smart のみです。
簡単なサンプルで試してみます。
import re pattern = re.compile(r'smart(?!phone)') print(bool(pattern.search('smart'))) >> True print(bool(pattern.search('smartphone'))) >> False print(bool(pattern.search('smartwatch'))) >> True result = pattern.search('smartwatch') print(result.group(0)) >> smart
肯定の後読み
肯定の後読みは、対象の文字列がパターン A の前にパターン B がある場合にマッチします。この時、マッチした値としてはパターン A にマッチした部分だけを取得します。
(?<=パターンB)パターンA 肯定後読み
例えば次のパターンで考えてみます。
r'(?<=digital)camera'
camera の直前に digital がある場合のみマッチします。 digitalcamera はマッチしますが、 camera や analogcamera はマッチしません。そしてマッチした文字列として取得するのは camera のみです。
簡単なサンプルで試してみます。
import re pattern = re.compile(r'(?<=digital)camera') print(bool(pattern.search('camera'))) >> False print(bool(pattern.search('digitalcamera'))) >> True print(bool(pattern.search('analogcamera'))) >> False result = pattern.search('digitalcamera') print(result.group(0)) >> camera
否定の後読み
否定の後読みは、対象の文字列がパターン A の前にパターン B がない場合にマッチします。この時、マッチした値としてはパターン A にマッチした部分だけを取得します。
(?<!パターンB)パターンA 否定後読み
例えば次のパターンで考えてみます。
r'(?<!digital)camera'
camera の直前に digital がない場合のみマッチします。 digitalcamera にはマッチしませんが、 camera や analogcamera はマッチします。そしてマッチした文字列として取得するのは camera のみです。
簡単なサンプルで試してみます。
import re pattern = re.compile(r'(?<!digital)camera') print(bool(pattern.search('camera'))) >> True print(bool(pattern.search('digitalcamera'))) >> False print(bool(pattern.search('analogcamera'))) >> True result = pattern.search('analogcamera') print(result.group(0)) >> camera
-- --
Python を使って正規表現で先読みと後読みを使用する方法について解説しました。
( Written by Tatsuo Ikura )
著者 / TATSUO IKURA
これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。