自分向け記事です。
import re
re.match(): パターンマッチング
pattern = re.compile() : 複雑なものは先にコンパイルしてからパターンマッチング
pattern.match()
match():先頭から一致
search():最初のマッチング(あれば)
findall():重なり合わないすべてのマッチリストを返す(あれば)
split():パターンにマッチしたところでソースを分割し部分文字列のリストを返す
sub():置換文字列を引数を取り、ソースのうちパターンにマッチするすべての部分を置換文字列に置き換える。
メタ文字 説明 例 マッチする例 マッチしない例
. 任意の一文字 a.c abc, acc, aac abbc, accc
^ 文字列の先頭 ^abc abcdef defabc
$ 文字列の末尾 abc$ defabc abcdef
* 0回以上の繰り返し ab* a, ab, abb, abbb aa, bb
+ 1回以上の繰り返し ab+ ab, abb, abbb a, aa, bb
? 0回または1回 ab? a, ab abb
{m} m回の繰り返し a{3} aaa a, aa, aaaa
{m,n} m〜n回の繰り返し a{2, 4} aa, aaa, aaaa a, aaaaa
[] 集合 [a-c] a, b, c d, e, f
| 和集合(または) a|b a, b c, d
() グループ化 (abc)+ abc, abcabc a, ab, abcd
start(), end(),span() による位置情報が必要な場合は inter()を使う!
iterを使用するとstart(),end()などが使える。
findallはlistを返すのでstart(),end()を持っていない。
m = re.finditer('[wsh]+', source)
for match in m:
print(match.group(), match.start(), match.end())
# span()を使ってまとめてstart/endを取得
m = re.finditer('[wsh]+', source)
for match in m:
start, end = match.span()
print(match.group(), start, end)
I (Iとスペース)の後ろにwishが続くところを探す print(re.findall('I (?=wish)', source))
wishの前にI(Iとスペース)があるところを探す print(re.findall('(?<=I) wish', source))
m = re.search(r'(. dish\b).*(\bfish)', source)
print(m.group(0)) # group(0)はマッチした部分全てを表す。
# つまり ' 'で囲った部分にマッチする部分をgroup(0)で受け取ることになる。
print(m.group(1)) # startはgroup(1)から a dish
print(m.group(2)) # fish
print(m.groups()) # ('a dish', 'fish')
(?P expr)という形式を使うとexprにマッチした部分は
nameという名前のグループに保存される。
m = re.search(r'(?P. dish\b).*(?P\bfish)', source)
print(m.group('DISH')) # a dish
print(m.group('FISH')) # fish
sedのような置換もできますね。
\1,\2がsedの置換方式と同じになります。なのであえて名前をつけて処理をしなくてもいいかな。。。という感触です。
source1 = '''I wish I may, I wish I might Have a dish of fish tonight.'''
source2 = re.sub(r'(.*dish\b)(.*)(\bfish)(.*)', r'\1\2\4', source1)
log = '{} =>\n{}'
print(log.format(source1, source2))
⇓結果
I wish I may, I wish I might Have a dish of fish tonight. =>
I wish I may, I wish I might Have a dish of tonight.