Python
正規表現

分かりやすいpythonの正規表現の例

基本の例

noComplieの方法

import re

# rを付けることを推奨。
# バックスラッシュをそのままで分かりやすいため。
content = r'hellow python, 123, end.' 
pattern = 'hel'

result = re.match(pattern, content)

if result: #none以外の場合
  print(result) 
  # output:<_sre.SRE_Match object; span=(0, 3), match='hel'>
  print(result.span()) 
  # output:(0, 3)
  print(result.group()) 
  # output:hel

complieの方法(推奨)
より処理が速い、複用もできる

import re

content = r'hellow python, 123, end.' 
pattern = 'hel'

# compile後match
repatter = re.compile(pattern)
result = repatter.match(content)

print(result.group())
#output:hel

正規表現の参照リスト

文字 説明 同様 マッチする マッチしない
\d 任意の数字 [0-9]
\D 任意の数字以外 [^0-9]
\s 任意の空白文字 [\t\n\r\f\v]
\S 任意の空白文字以外 [^\t\n\r\f\v]
\w 任意の英数字 [a-xA-Z0-9_]
\W 任意の英数字以外 [\a-xA-Z0-9_]
\A 文字列の先頭 ^
\Z 文字列の末尾 $
. 任意の一文字 - 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

ターゲット文字の取得(group(x))

import re

# rを付けることを推奨。
# バックスラッシュをそのままで分かりやすいため。
content = r'hellow python, 123,end' 
# ()で取りたい文字を
pattern = '.*?(\d+).*'

result = re.match(pattern, content)

if result: #none以外の場合
  # group()で全文字を
  print(result.group())  # hellow python, 123,end
  # group(1)で数字を
  print(result.group(1)) # 123

.*と.*?の区別 (重要:結果が予想外の原因はほぼこちら)

.*でなるべく多い文字をマッチする
.*?でなるべく少ない文字をマッチする(普段はこれを使う)

import re

content = r'hellow python, 123,end'

# .*でなるべく多い文字をマッチするため、12は.*に含まれる
pattern1 = '.*(\d+)'
# .*?でなるべく少ない文字をマッチするため、123は\dにの残る
pattern2 = '.*?(\d+)'

result1 = re.match(pattern1, content)
result2 = re.match(pattern2, content)

if result1:
  print(result1.group(1))
  # output:3

if result2:
  print(result2.group(1))
   # output:123

改行について

matchで引数を指定して、.*が改行を識別できる。

import re

content = r'''hellow python,
          enter,123
          end'''

pattern = '.*?\d+'

# re.Sをしていないため、.*は改行を識別できない
result1 = re.match(pattern, content)
# re.Sをしていたため、.*は改行を識別できる
result2 = re.match(pattern, content, re.S)

if result1:
  print('result1:', result1.group())
else:
  print('result1:none')
# output:result1:none

if result2:
  print('result2:', result2.group())
else:
  print('result2:none')
# output:result2: hellow python,
#         enter,123

search()

matchなら、先頭からピッタリする必要がある
searchに替わると、存在するだけで結果が出る

import re

content = r'hellow python'

pattern = 'python'

# matchなら、先頭からピッタリする必要がある
match_result = re.match(pattern, content)
# searchなら、存在するだけで結果が出る
search_result = re.search(pattern, content)

if match_result:
  print('match_result:', match_result.group())
else:
  print('match_result:none')
# output:match_result:none

if search_result:
  print('search_result:', search_result.group())
else:
  print('search_result:none')
# output:search_result: python

findall()

searchは最初の結果を戻る
findallはすべての結果をlist型で戻る

import re

html = '''<div id="songs-list">
    <h2 class="title">songs</h2>
    <p class="introduction">
        classic songs
    </p>
    <ul id="list" class="list-group">
        <li data-view="1" class="active">
            <a href="/again.mp3" singer="Yui">again</a>
        </li>
        <li data-view="2"><a href="/Darling.mp3" singer="西野カナ">Darling</a></li>
        <li data-view="3"><a href="/手をつなぐ理由.mp3" singer="西野カナ">手をつなぐ理由</a></li>
    </ul>
</div>'''

pattern = '<li.*?singer="(.*?)">(.*?)</a>'

# findall 
results = re.findall(pattern, html, re.S)

# Type:list
print(type(results))

# 抽出
for result in results:
    print(result[0], result[1])

結果

<class 'list'>
Yui again
西野カナ Darling
西野カナ 手をつなぐ理由

sub()で便利にreplace

sub()で余計な情報を除いてから、正規式がもっと簡単に

import re

html = '''<div id="songs-list">
    <h2 class="title">songs</h2>
    <p class="introduction">
        classic songs
    </p>
    <ul id="list" class="list-group">
        <li data-view="4" class="active">
            <a href="/again.mp3" singer="Yui">again</a>
        </li>
        <li data-view="6"><a href="/Darling.mp3" singer="西野カナ">Darling</a></li>
        <li data-view="5"><a href="/手をつなぐ理由.mp3" singer="西野カナ">手をつなぐ理由</a></li>
    </ul>
</div>'''

# subでaを除き
html = re.sub('<a.*?>|</a>', '', html)
# 正規は簡単にできる
pattern = '<li.*?>(.*?)</li>'

# findall 
results = re.findall(pattern, html, re.S)
# 歌名を出力
for result in results:
    print(result.strip())

結果

again
Darling
手をつなぐ理由