Python(パイソン)講座、第8回目です。
前回は文字列操作について紹介しました。
今回は正規表現についてです。
Python に限ったことではないのですが、正規表現を知っていると簡単に解決するということは意外とあったりします。
というわけで早速見ていきましょう。
正規表現とは
正規表現は文字列を一つのパターン化した文字列で表現する方法です。
それでは、どんな感じなのか使ってみましょう。
\d{3}-\d{4}-\d{4}
これは携帯電話の番号の桁を正規表現で表したものです。
携帯電話の番号の特徴は下記の通りです。
- 3桁の数字 -(ハイフン) 4桁の数字 -(ハイフン) 3桁の数字という形
- 文字数はハイフンを入れると13文字
あと 080 や 090 で始まるとかありますが、今回は除外しています。
携帯電話の番号のパターンになっているかということを調べる場合。
例えば、正規表現がなかったとすると、文字数が13文字かとか、4文字目にハイフンがあるかとか、9文字目にハイフンがあるかとか。
とにかく色々判定しなければいけないので面倒です。
しかし、正規表現があれば、こんな面倒なことはやらなくて良いのです。
【捕捉事項】raw文字列
本来ならば、前回の文字列のところで紹介しておくべき内容だったのですが。
正規表現を使う場合、この raw文字列 を扱う機会が多いので紹介しておきます。
raw文字列 は、生の文字列を意味します。
\(バックスラッシュ)や ‘(シングルクォート)などは、プログラム上特別な意味を持ちます。
しかし、raw文字列 は、そういった意味を無視して、例えば、バックスラッシュはバックスラッシュとして扱います。
print(r'文字列')
といった感じで先頭に r を付けることで文字列内のエスケープシーケンスなどを無効にできます(例として print関数を使用)。
正規表現の記号
正規表現で使う記号を紹介します。
- ^ → 先頭から
- $ → 末尾から
- ? → 直前のグループの0回か1回の出現にマッチ
- * → 直前のグループの0回以上の出現にマッチ
- + → 直前のグループの1回以上の出現にマッチ
- {n} → 直前のグループのn回の出現にマッチ
- {n,} → 直前のグループのn回以上の出現にマッチ
- {,n} → 直前のグループの0~n回の出現にマッチ
- {n,m} → 直前のグループのn~m回の出現にマッチ
- . → 改行文字以外の任意の1文字
集合を表す正規表現の使い方です。
- [abc] → a,b,c の意味(括弧が集合の意味)
- [a-z] → a~z の意味(範囲指定)
- [^abc] → a,b,c 以外の意味(否定)
特殊シーケンス
数字、アルファベットなどよく使う表現は特殊シーケンスとして利用できます。
最初に紹介した携帯電話番号の例は特殊シーケンスを使っています。
- \d → 任意の数字
- \D → 任意の数字以外
- \w → 任意の英数字
- \W → 任意の英数字以外
- \s → スペース、タブ、改行
- \S → スペース、タブ、改行以外
Python で正規表現を使うには
Pythonで正規表現を使うには、reモジュールをインポートする必要があります。
import re
と記述することで、reモジュールをインポートすることができます。
searchメソッド、groupメソッド
searchメソッドは渡された文字列の中から正規表現にマッチする部分を探します。
groupメソッドは searchメソッドでマッチした文字列を取得します。
import re match = re.search(r'\d+', 'Hello. My name is Pasota. I am 36 years old.') print('文字列内で数字の部分:' + match.group())
この場合の実行結果は下記の通りです。
文字列内で数字の部分:36
findallメソッド
searchメソッドは、最初に見つかった文字列をオブジェクトとして返します。
それに対して findallメソッドは、見つかったすべての文字列を返します。
import re print( re.findall(r'\d+', 'Hello. My name is Pasota 55. I am 36 years old.') )
この場合、実行結果は下記の通りです。
['55', '36']
compile関数を使う
compile関数 に正規表現を渡すと 正規表現オブジェクトを返してくれます。
同じパターンを何度も利用するときは便利ですし、高速に処理されます。
import re pattern = re.compile(r'\d+') num_one = pattern.search('Hello. My name is Pasota. I am 36 years old.') num_two = pattern.search('Windows 95') print('文字列内で数字の部分:' + num_one.group()) print('文字列内で数字の部分:' + num_two.group())
この場合の実行結果は下記の通りです。
文字列内で数字の部分:36 文字列内で数字の部分:95
最後に
いかがでしょうか。
簡単な例しか紹介していませんが、正規表現は複雑な文字列の処理を行うときに便利です。
私もまだまだ未熟なのでしっかりと勉強していきたいと思います。