Python(正規表現)
正規表現とは、文字列をパターンを用いて表現するものです。正規表現を使うと、文字列の検索や置換で大きな力を発揮します。正規表現では、通常の文字に加えて、メタキャラクタという特殊文字で、文字列のパターンを表現します。
ちなみに、正規表現に似ているのがワイルドカード「*」で、0文字以上の任意の文字を表すメタキャラクタです。 Pythonで正規表現を使う場合、reモジュールを読み込みます。
そして、正規表現のパターンを記述する際にはraw string記法「r"..."」を用います。この記法では、Python文字列における\(バックスラッシュ)を無効にできます。
re.match(pat,str) と re.search(pat,str) は似ているが、 re.match(pat,str) の方は、必ず文字列の先頭からpatがマッチしていなければならない点で異なる。
文字列の末尾を表すメタキャラクタ「$」
「.」は任意の一文字を表す
直前の文字の繰り返しを表現するメタキャラクタ
「*」は0回以上の繰り返し
「+」は1回以上の繰り返し
「?」は0回か1回の繰り返し
「{m}」はm回の繰り返し
「{m,n}」はm回以上n回以下の繰り返し
「{m,}」はm回以上の繰り返し
正規表現では最長一致が基本
末尾に「?」をつけるとマッチする部分を最小単位に抑えることができる
「[0123456789]」は数字のいずれか、連続した文字指定は「[0-9]」と指定できる
「[0-9]」はよく使うパターンなので「\d」と記述できる
「\b」単語の境界
「\d」数字
「\D」数字以外
「\w」Unicode文字
「\W」Unicode文字以外
「\s」空白文字
「\S」空白文字以外
単語の選択"|"
アメリカ英語「color」とイギリス英語「colour」のどちらにもマッチさせたい場合
「(color|colour)」あるいは「colo(r|ur)」と記述
ちなみに、正規表現に似ているのがワイルドカード「*」で、0文字以上の任意の文字を表すメタキャラクタです。 Pythonで正規表現を使う場合、reモジュールを読み込みます。
そして、正規表現のパターンを記述する際にはraw string記法「r"..."」を用います。この記法では、Python文字列における\(バックスラッシュ)を無効にできます。
# 正規表現
import re # 正規表現reモジュールを取り込む
pat = r"\d+" # raw stringの記述
string = "This pen is 100yen."
repl = 200
# 正規表現検索 どこかにマッチするかを調べてmatchオブジェクトを返す。見つからない場合はNone
re.search(pat,string)
# 文字列の先頭からマッチするかを調べてmatchオブジェクトを返す。見つからない場合はNone
re.match(pat,string)
re.split(pat,string)
re.findall(pat,string)
re.finditer(pat,string)
re.sub(pat,repl,string)
re.compile(pat)
英文の中にある数値を検索する正規表現「\d+」
reモジュールで使える関数一覧
関数 | 説明 |
re.match(pat,str) | patが文字列strの先頭からマッチするかを調べてmatchオブジェクトを返す。見つからない場合はNone |
re.search(pat,str) | 正規表現検索 patがstrのどこかにマッチするかを調べてmatchオブジェクトを返す。見つからない場合はNone |
re.split(pat,str) | patでstrを分割してリストを返す |
re.findall(pat,str) | strの中でpatにマッチするものすべてを取り出し、文字列のリストとして返す |
re.finditer(pat,str) | strの中でpatにマッチするものすべて探すイテレータとして返す |
re.sub(pat,repl,str) | strの中でpatにマッチするものをreplに置換する |
re.compile(pat) | patをあらかじめコンパイルする |
import re
words=["orange","october","octpus","order","banana","baby","busy"]
# 正規表現のパターンに一致するものを画面に出力
pattern = r"oc.*"
print("ocで始まるパターン=",pattern)
for word in words:
if re.match(pattern,word):
print("-",word)
pattern = r"b.*y"
print("bで始まりyで終わるパターン=",pattern)
for word in words:
if re.match(pattern,word):
print("-",word)
matchオブジェクトについて
プロパティ | 意味 |
match.expand(template) | sub()メソッドと同様にマッチした文字列でtemplate文字列を置換 |
match.group([g]) | マッチしたサブグループgを返す |
match.groups() | パターンにマッチしたサブグループの一覧を返す |
match.groupdict() | 名前付きのサブグループを辞書型で返す |
match.start([g]) | グループgとマッチした部分文字列の先頭のインデックスを返す |
match.end([g]) | グループgと マッチした部分文字列の末尾のインデックスを返す |
match.span([g]) | グループgに関して、(start,end)のタプルを返す |
import re # 正規表現reモジュールを取り込む
# 先頭と末尾の指定があるので「abc」の文字列だけにマッチ
re.search(r"^abc$","abc")
# abcdやxabcはマッチしない
print(re.search(r"^abc$","abcd"))
print(re.search(r"^abc$","xabc"))
# 任意のファイル拡張子を調べる
pat = r"\.png$"
re.search(pat,"abc.png")
# 末尾が.pngでなければマッチしない
print(re.search(pat,"abc.png-doc.txt"))
words = ["soy","soup","nuts","spot"]
pat = r"^s...$" # sから始まる4文字の文字列
[i for i in words if re.search(pat,i)]
# 繰り返し
re.search(r"ba*","b")
print(re.search(r"ba+","b"))
re.search(r"ba?","b")
re.search(r"ba*","baaaaaaa")
re.search(r"ba+","baaaaaaa")
re.search(r"ba?","baaaaaaa")
re.search(r"ba{3}","baaaaaaa")
re.search(r"ba{1,3}","baaaaaaa")
re.search(r"ba{3,}","baaaaaaa")
文字列の先頭を表すメタキャラクタ「^」文字列の末尾を表すメタキャラクタ「$」
「.」は任意の一文字を表す
直前の文字の繰り返しを表現するメタキャラクタ
「*」は0回以上の繰り返し
「+」は1回以上の繰り返し
「?」は0回か1回の繰り返し
「{m}」はm回の繰り返し
「{m,n}」はm回以上n回以下の繰り返し
「{m,}」はm回以上の繰り返し
正規表現では最長一致が基本
末尾に「?」をつけるとマッチする部分を最小単位に抑えることができる
import re
# 最小単位の繰り返し
s= "赤巻紙青巻紙黄巻紙"
re.findall(r".+紙",s)
re.findall(r".+?紙",s)
# 文字集合の指定[...]
zipre = re.compile(r"^[0-9]{3}\-[0-9]{4}$") # 正規表現パターンをコンパイル
zipre.search("440-0012")
print(zipre.search("4401-0012"))
# 単語の選択"|"
s = "I like red colour."
pat = r"\w+ (color|colour)"
re.search(pat,s)
# グループ(...)
s = "date:2019/10/15"
pat = r"(\d{4})/(\d{1,2})/(\d{1,2})"
g=re.search(pat,s)
「[abc]」abcのいずれかの文字「[0123456789]」は数字のいずれか、連続した文字指定は「[0-9]」と指定できる
「[0-9]」はよく使うパターンなので「\d」と記述できる
「\b」単語の境界
「\d」数字
「\D」数字以外
「\w」Unicode文字
「\W」Unicode文字以外
「\s」空白文字
「\S」空白文字以外
単語の選択"|"
アメリカ英語「color」とイギリス英語「colour」のどちらにもマッチさせたい場合
「(color|colour)」あるいは「colo(r|ur)」と記述