先読みと後読みを使ったパターンの記述

正規表現における先読みと後読みは、マッチするかどうか確認は行うけれどマッチした文字列としては取得しないときに利用します。先読みには肯定先読みと否定先読み、後読みには肯定先読みと否定先読み、がそれぞれ用意されています。ここでは 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 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。