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

## 基本の例
noComplieの方法

```python3
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の方法（推奨）
より処理が速い、複用もできる

```python3
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
*|０回以上の繰り返し|-|ab*|a, ab, abb, abbb|aa, bb
+|１回以上の繰り返し|-|ab+|ab, abb, abbb|a, aa, bb
?|０回または１回|-|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))
```python3
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
```

***
## .\*と.\*?の区別　（重要：結果が予想外の原因はほぼこちら）
.\*でなるべく多い文字をマッチする
.\*?でなるべく少ない文字をマッチする<font color="Red">（普段はこれを使う）</font>

```python3
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で引数を指定して、.*が改行を識別できる。

```python3
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に替わると、存在するだけで結果が出る

```python3
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型で戻る

```python3
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()で余計な情報を除いてから、正規式がもっと簡単に

```python3
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
手をつなぐ理由
```