LoginSignup
2
1

More than 3 years have passed since last update.

正規表現 先読み、後ヨミ

Last updated at Posted at 2020-03-16

前提としてライブラリreをインポートしている状態です。

import re

下記の記法は全てテキスト部分のみ抽出をするもので、抽出時の条件がグループ()で示されています。
肯定はグループ内のテキスト条件も一致していた場合に抽出。
否定はグループ内のテキスト条件が一致していなかった場合に抽出。

名称 記載方法 概要
肯定先読み テキスト(?=xxx) xxxが一致したときにテキスト部分を取得
否定先読み テキスト(?!xxx) xxxが一致しなかったときにテキスト部分を取得
肯定後読み (?<=xxx)テキスト xxxが一致したときにテキスト部分を取得
否定後読み (?<!xxx)テキスト xxxが一致しなかったときにテキスト部分を取得

肯定先読み

抽出したいテキストに続けて(?=xxx)を入れることで抽出したいテキストが一致 且つ xxx部分も一致していた場合にテキスト部分を抽出

re.findall('AB(?=CDEF)', 'ABCDEF') #['AB']
re.findall('AB(?=DEF)', 'ABCDEF') #[]
re.findall('AB(?=CD)', 'ABCDEF') #['AB']
re.findall('.+(?=CD)', 'ABCDEF') #['AB']
re.findall('AB(?=[A-Z]{2,3})', 'ABCDEF') #['AB']

否定先読み

否定先読みでは抽出したいテキストの後ろに(?!xxx)を記載。
テキスト部分が一致 且つ xxx 部分が一致していない場合にテキスト部分を抽出

re.findall('AB(?!CDEF)', 'ABCDEF') #[]
re.findall('AB(?!DEF)', 'ABCDEF') #['AB']
re.findall('AB(?!CD)', 'ABCDEF') #[]

否定しているので先読みとは逆の結果になります。

肯定後読み

(?<=xxx)に続けて抽出したいテキストを記載することでxxx部分が一致 且つ テキストが部分も一致した場合にテキスト部分を抽出

re.findall('(?<=ABCD)EF', 'ABCDEF') #['EF']
re.findall('(?<=BC)EF', 'ABCDEF') #[]
re.findall('(?<=)EF', 'ABCDEF') #['EF']

否定後読み

(?<!xxx)に続けて抽出したいテキストを記載することでxxx部分がしていなくて 且つ テキストが部分も一致した場合にテキスト部分を抽出

re.findall('(?<!ABCD)EF', 'ABCDEF') #[]
re.findall('(?<!BC)EF', 'ABCDEF') #['EF']
re.findall('(?<!)EF', 'ABCDEF') #[]

肯定先読みの応用

text = 'Python python PYTHON'

re.findall('py(?=thon)', text) #['py']
re.findall('Py|py(?=thon)', 'Python python PYTHON') #['Py', 'py']
re.findall('py(?=thon)', 'Python python PYTHON', re.IGNORECASE) #['Py', 'py', 'PY']

スクレイピングでありそうな使用方法

text = '住所:東京都新宿区〇〇 〇〇タワー\r地図はこちら'
re.findall('(?<=:).*(?=\r)', text)[0] #東京都新宿区〇〇 〇〇タワー

【参考サイト】
正規表現の先読み・後読みを極める!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1