Pythonによる正規表現(サンプルコード付き)

#概要
正規表現とは簡潔に書くと、いくつかの文字列を一つの形式で表現するための表現方法。
正規表現は文字列操作の関数と組み合わせで使われ、メタ文字と呼ばれる特殊文字を用いることでより複雑な操作を可能にする。ここではPythonを用いて、そのメタ文字の紹介と使い方及び実例を示す。なお、reモジュールの関数をすべて説明するとごちゃごちゃするためまた違う記事で書く。
よってここでは、sub関数のみを使って正規表現のみにスポットを当てていくつもりだ。
#基本編
## sub関数の説明
[re-正規表現の説明](https://docs.python.jp/3/library/re.html)

```py
re.sub(pattern, repl, string, count=0, flags=0)
```

pattern : 正規表現パターン
repl : 置換する文字列
string : 置換される文字列
count : 置換回数
count と flags　はオプション
## . (ピリオド)
. は任意の一文字にマッチする。
###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'HelloTWorld'
pattern = r'Hello.World'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : HelloTWorld is replaced


```

このスクリプトからtextがpatternにマッチしたため、textは 'is replaced'に置き換えられてますね。では次のようなtextではどうでしょうか。

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'HelloTTWorld'
pattern = r'Hello.World'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : HelloTTWorld HelloTTWorld
```
このプログラムでは、マッチしてないため置き換えられずresult の中がHelloTTWorldとなることがわかる。' . ' は一文字のみというところがポイントですね。

# ^(べき乗)
行の最初にマッチする。
###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'Hello'
pattern = r'^Hello'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : Hello is replaced
```

もし ```pattern = r'^Hellow' ``` だとマッチせず異なる結果となってしまいます。

#$(ドルマーク)
行の最後にマッチする。
###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'Hello'
pattern = r'Hello$'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : Hello is replaced
```

もし ```pattern = r'aHello$'``` だとマッチせず異なる結果となってしまいます。

#*(アステリスク)
一文字に続く * は0回以上の表現の繰り返しにマッチする。
###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'Hello'
pattern = r'Hel*o'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : Hello is replaced
```

0回以上なのでもちろん ``` text = 'Heo World' ```　でもマッチする。

#+(プラス)
一文字に続く + は1回以上の表現の繰り返しにマッチする。
アスタリスクとの違いは0回以上か1回以上かの違いのみです。

###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'Hello'
pattern = r'Hel+o'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : Hello is replaced
```

 ``` text = 'Heo World' ```　ではマッチしません。

#?(疑問符)
疑問符は直前の表現が0個か1個のときマッチする。

###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'Hello World'
pattern = r'Hello ?World'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : Hello World is replaced
```

このように、半角の空白(一文字)あり、なしの文字列を同一視する際には便利そうだね。
(例)090-XXXX-XXXX


#{m}
直前のグループの m 回の繰り返しにマッチする。
ここで言うグループはあとで示す。

###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'Hello'
pattern = r'Hel{2}o'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : Hello is replaced
```


#{m,n}
直前のグループの m 回以上 n 回以下の繰り返しにマッチする。
ここで言うグループはあとで示す。

###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'Hello'
pattern = r'Hel{1,3}o'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : Hello is replaced
```
この場合、```text = 'Helo'``` や ```text = 'Helllo'```でもマッチします。


#() 
これは、文字列をグループ化することができる。
{m}や{m,n}のグループとはこのことである。

###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'HeHeo'
pattern = r'(He){2}o'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : HeHeo is replaced
```
このプログラムでは{m}との組み合わせで使っている。今までのプログラムは一文字のみを対象に文字列操作をしたが、この()を用いることで文字列を対象にすることができる。


# \[](大かっこ)
括弧内に含まれる一文字にマッチする。

###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'Hello'
pattern = r'He[el]lo'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : Hello is replaced
```

ここでは、```text = 'Heelo'```でもマッチすると思う。
しかし、 ```text = 'Heello'``はマッチされない。


#|(縦棒)
縦棒は選択肢にマッチする。

###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'Hello World'
pattern = r'Hello|test|a'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : Hello World is replaced World
```

ここでは、HelloはマッチしてWorldの方はマッチされていないですね。

#特殊シーケンス
メタ文字以外に￥(windownsの場合　Linuxの場合は \\ )と組み合わせた特殊シーケンスというものを大雑把に紹介する。ちなみに、この特殊シーケンスはメタ文字を使って同様の表現をすることができるので、ついでにそっちも紹介しよう。

| 特殊シーケンス|説明 |メタ文字 |
|:--:|:--:|:--:|
|\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|文字列の末尾|$|
ちなみに \t はタブ、\n は改行(LF)、\r は復帰(CR)、\f は用紙送り文字、\v は垂直タブの意味である。

#エスケープについて
もし検索、文字列の中にメタ文字がある際はどうすれば良いのでしょうか？そのような時に使われるのが、エスケープ文字である\(windowsなら¥)なのだ。
###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = '^Hello'
pattern = r'^\^Hello'

result = re.sub(pattern,'is replaced',text)
print(text + ' ' + result) #結果 : ^Hello is replaced
```

このように、パターンの文字列がメタ文字が含まれている際は普通の文字として認識して欲しいメタ文字の前に \をつけてあげましょう。

#応用編(メタ文字の組み合わせ)
さてここまで様々なメタ文字の使い方を見てきたがここで、復習ついでにメタ文字の組み合わせをしてみよう。

###例

```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = 'Hello'
pattern = r'H.*'

result = re.sub(pattern,'match',text)
print(text + ' ' + result) #結果 : Hello match
```



```py
# -*- coding:utf-8 -*-
#!/usr/bin/env python3

import re

text = '012-3456'
pattern = r'[0-9]{3}-[0-9]{4}'

result = re.sub(pattern,'match',text)
print(text +" "+result) #結果 :012-3456 match

```

応用編とか書いたけど、良い例が思いつかなかった。

#参照
[正規表現](https://ja.wikipedia.org/wiki/正規表現)