LoginSignup
858
828

More than 3 years have passed since last update.

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

Last updated at Posted at 2018-01-25

基本の例

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-zA-Z0-9_]
\W 任意の英数字以外 [\a-zA-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
手をつなぐ理由
858
828
4

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
858
828