Top 5
正規表現のre.search().groups()とre.findall()の違い【Python】
Oct. 11, 2019, 12:12 a.m. edited Dec. 21, 2019, 5:19 a.m.大学のプログラミングの授業(Python)でTAをしているのですが、ここで
abc123xyz
に含まれる数字を正規表現で抜き出す(出力例は123
)という課題が出ました1。この解法として、
>>> import re
>>> re.search('\d+', 'abc123xyz').group()
'123'
があります。一方、ここで
>>> re.search('\d*', 'abc123xyz').group()
''
とすると空文字列が返ってきます。正規表現は最長一致を返すのにもかかわらず、なぜこうなるのかと質問が出ました。
.groups()
とre.findall()
の違い
この挙動を理解するには正規表現のグループとマッチした文字列全体の違いについて知らなければなりません。理解しやすくするために問題を少し変えて
abc123xyz456
とします。すると、
>>> re.search('\d+', 'abc123xyz456').group()
'123'
となります。これはre.search()
は最初にマッチした文字列全体2を返すためです。ここで、groups()
もありますが、その結果は
>>> re.search('\d+', 'abc123xyz456').groups()
()
と何もありません。それもそうで、正規表現中でグループ(()
)を指定していないためです。そこで、\d+
をグループで括ってやると、
>>> re.search('(\d+)', 'abc123xyz456').groups()
('123',)
と得られます。これだとグループの恩恵がわかりづらいので、数字の前のアルファベットもグループで括ると、
>>> re.search('([A-Za-z]+)(\d+)', 'abc123xyz456').groups()
('abc', '123')
となります。ここでgroup()
には引数を渡すことができ、
>>> re.search('([A-Za-z]+)(\d+)', 'abc123xyz456').group(1)
'abc'
>>> re.search('([A-Za-z]+)(\d+)', 'abc123xyz456').group(2)
'123'
>>> re.search('([A-Za-z]+)(\d+)', 'abc123xyz456').group() # .group(0)と同じ
'abc123'
と引数でグループの何番目の文字列を得るかを指定できます。引数を与えない場合のデフォルトが0
であり、これはマッチした文字列全体を返します。
一方、.groups()
と混同しやすいre.findall()
では何を返すかというと、
>>> re.findall('([A-Za-z]+)(\d+)', 'abc123xyz456')
[('abc', '123'), ('xyz', '456')]
とマッチした文字列全体をすべて見つけて返します。
つまり、.groups()
は最初にマッチした文字列全体の中でグループに分けて返し、一方re.findall()
はすべてのマッチした文字列全体をそれぞれグループに分けて返すという違いがあります。
冒頭の問題の答え
re.findall()
をすれば理由は明らかとなります。
>>> re.findall('\d+', 'abc123xyz')
['123']
>>> re.findall('\d*', 'abc123xyz')
['', '', '', '123', '', '', '', '']
つまり、\d*
はa
やb
の間にあるような空文字列に対しても最長一致でマッチした文字列全体と認識するので、re.search()
は最初に見つかったマッチした文字列全体である''
を返していたということになります。
Top 5
git checkout hogeしてerror: pathspec 'hoge' did not match any file(s) known to gitとなったときの対処法【Git】
Oct. 13, 2019, 12:57 a.m.GitHubからpullするときにfatal: refusing to merge unrelated historiesとエラーが出るときの対処法
Aug. 13, 2019, 3:41 a.m.NumPyで標準誤差を計算する【Python】
Feb. 4, 2020, 2:24 a.m.<model-viewer>でアニメーションつきモデルをAndroid【Scene Viewer】, iOS【AR Quick Look】で表示してみた
Aug. 15, 2019, 4:02 a.m.OverleafのBibTeXでjunsrtを使う
Jan. 8, 2019, 1:30 a.m.Tags
- #Python (16)
- #Unity (9)
- #Mac (6)
- #AoE2 (5)
- #Bash (5)
- #数学 (4)
- #シミュレーション (4)
- #Docker (4)
- #Android (4)
- #NumPy (4)
- #量子力学 (3)
- #相対論 (3)
- #GitHub (3)
- #Linux (3)
- #Django (2)
- #意識 (2)
- #Rust (2)
- #PyO3 (2)
- #Qiskit (2)
- #AR (2)
- #Git (2)
- #iOS (2)
- #C++ (2)
- #正規表現 (2)
- #電磁気学 (1)
- #情報理論 (1)
- #Google Drive (1)
- #Overleaf (1)
- #LaTeX (1)
- #Let's Encrypt (1)
- #ポケモン (1)
- #AdMob (1)
- #Autoya (1)
- #docopt (1)
- #SymPy (1)
- #AWS (1)
- #Twitter (1)