Python の正規表現で電話番号を抽出します。
正規表現って難しいですよね。難しい記号だらけで訳がわかりません。しかし、その難しさに比例し、機能としては強力なものになっています。
Contents
Python の正規表現 re モジュール
import re
まず、Python で正規表現を使うには re モジュールをインポートします。この re モジュールに、正規表現関連すべての関数が入っています。
正規表現オブジェクトを生成 compile()
phone_regex = re.compile(r'''( (\d{2,4}|\(\d{2,4}\)) # 市外局番 (\s|-) # 区切りは空白もしくはハイフン (\d{3,4}) # 市内局番 (\s|-) # 区切りは空白もしくはハイフン (\d{4}) # 加入者番号 )''', re.VERBOSE)
次に正規表現オブジェクトを生成します。電話番号を抽出する正規表現オブジェクトを生成しています。詳細については、以下の通りです。
(\d{2,4}|\(\d{2,4}\))
市外局番は、2〜4桁の数字(\d)または括弧で囲われた2〜4桁の数字でマッチするようにしています。
今回、市外局番は必須としていますが、任意にしたい場合は、? を最後に追加すれば良いでしょう。
(\s|-)
区切り文字は、空白(\s)またはハイフンでマッチするようにしています。
こちらも任意にしたい場合は、最後に ? を追加すれば良いでしょう。
re.VERBOSE
正規表現内にコメントを書けるようにするためのオプションです。
マッチする最初の場所を探す search()
# 区切り文字がないので、マッチしない test1 = '0123456789' m = phone_regex.search(test1) print('test1:', m) # test1: None # マッチする test2 = '012-345-6789' m = phone_regex.search(test2) print('test2:', m) # test2: <_sre.SRE_Match object; span=(0, 12), match='012-345-6789'> # マッチするのは、最初の1つ test3 = '012-345-6789 987 654 3210' m = phone_regex.search(test3) print('test3:', m) # test3: <_sre.SRE_Match object; span=(0, 12), match='012-345-6789'>
compile 関数で生成したオブジェクトをもとに、search 関数で電話番号を抽出します。
search 関数は、マッチする最初の場所を探す関数です。マッチしない場合は、None を返します。
マッチする最初の場所を探すので、マッチ対象が複数あったとしても、最初の一つしか抽出しません。
マッチするすべてを探す findall()
# 全てマッチする test4 = test3 l = phone_regex.findall(test4) print('test4:', l) # test4: [('012-345-6789', '012', '-', '345', '-', '6789'), ('987 654 3210', '987', ' ', '654', ' ', '3210')]
search 関数は最初の一つしか抽出しませんが、findall 関数は、マッチした全てを抽出できます。search を使うか、findall を使うかは、その時々によって使い分けましょう。
Python の正規表現で電話番号を抽出
import re phone_regex = re.compile(r'''( (\d{2,4}|\(\d{2,4}\)) # 市外局番 (\s|-) # 区切りは空白もしくはハイフン (\d{3,4}) # 市内局番 (\s|-) # 区切りは空白もしくはハイフン (\d{4}) # 加入者番号 )''', re.VERBOSE) # 区切り文字がないので、マッチしない test1 = '0123456789' m = phone_regex.search(test1) print('test1:', m) # test1: None # マッチする test2 = '012-345-6789' m = phone_regex.search(test2) print('test2:', m) # test2: <_sre.SRE_Match object; span=(0, 12), match='012-345-6789'> # マッチするのは、最初の1つ test3 = '012-345-6789 987 654 3210' m = phone_regex.search(test3) print('test3:', m) # test3: <_sre.SRE_Match object; span=(0, 12), match='012-345-6789'> # 全てマッチする test4 = test3 l = phone_regex.findall(test4) print('test4:', l) # test4: [('012-345-6789', '012', '-', '345', '-', '6789'), ('987 654 3210', '987', ' ', '654', ' ', '3210')]
上記で説明した内容を合体し、main.py というファイルに保存しました。
この main.py を実行すると、以下のような結果になります。
$ python main.py test1: None test2: <_sre.SRE_Match object; span=(0, 12), match='012-345-6789'> test3: <_sre.SRE_Match object; span=(0, 12), match='012-345-6789'> test4: [('012-345-6789', '012', '-', '345', '-', '6789'), ('987 654 3210', '987', ' ', '654', ' ', '3210')] $
まとめ
Python の正規表現で電話番号を抽出しました。
正規表現は、入力フォームのバリデーションルールだったり、ログを解析するときだったりと、様々なシーンで使用します。
ある人は、「正規表現を知っているのは、問題を解くのに3,000ステップもかかっていたものが、3ステップで済むくらいの違いがある」と言っているほど強力な機能です。
是非ともマスターしたいスキルですね。