スクレイピングしてきたraw_htmlから電話番号を抜き出すときの正規表現。いわゆる通常の000−000−0000というような3桁3桁4桁のハイフンありだけでなく、、、
- 00-0000-0000
- 0000-00-0000
- 0120-000-000
更には、
- (00)0000-0000
- (0120)000000
のような、ハイフンの代わりに()であったり、ハイフンがなかったりのパターンにも対応する。
コード
import re
url = 'http://www.hogehoge'
result = urlfetch.fetch(url)
raw_html = result.content
pattern = r'^\d{2,4}-|)|)\d{2,4}-\d{3,4}'
tel_number = re.findall(pattern, raw_html)
普通の電話番号、フリーダイヤル、FAXがリストになって返ってくるのでどうやって電話番号だけにするかが課題。最初に電話番号、TEL、フリーダイヤルとかでsplit
しておけばいいんじゃなかろうかと思われる。(このままではハマる。下のハマったを参照。)
エラー対応
error: unbalanced parenthesis
pattern = r'^\d{2,4}-|)|)\d{2,4}-\d{3,4}'
の半角括弧閉じをエスケープしないとダメ
pattern = r'^\d{2,4}-|\)|)\d{2,4}-\d{3,4}'
でOK。
ていうか、[-))]
ってすればエスケープいらない。最終的にはバックスラッシュ必要だった。ハマったの最後を参照。
Unbalanced parenthesis python
ハマった
pattern = r'^\d{2,4}[-))]\d{2,4}-\d{3,4}'
から苦闘した。
^
つけっぱ事件
raw_html
が??0120-000-000
なのにずっと先頭に^
をつけっぱで検出できずムダにハマった。馬鹿ですね。
[-))]
が上手くいかない
全角かっこのとじる「)」を検出できない。トチ狂って[-))]*
を.*
としてみた。
当然、ダイヤル(0120)000-000 電話(03)0000-0000
は0120)000-000 電話(03)0000-0000
と抜き出される。
あれ?なんで??みたいな。
さらにさらに、最後に$
をつけるという極めつけ。結果は変わりません。
raw_html
を半角に変換する
import re
import unicodedata
url = 'http://www.hogehoge'
result = urlfetch.fetch(url)
raw_html = unicodedata.normalize('NFKC', result.content)
pattern = r'\d{2,4}[-)]*\d{2,4}-\d{3,4}$'
tel_number = re.findall(pattern, raw_html)
print tel_number
ダイヤル(0120)000-000 電話(03)0000-0000
-> 03)0000-0000
なんだかいいカンジになってきた。$
が邪魔して、フリーダイヤル部分が取れてないので$
をとる。
全角カッコをunicodeで書いてみる
ログにu'0120\uff09000-000\u3000\u96fb\u8a71\uff0803\uff090000-0000'
を発見。もしかして。。。
pattern = r'[(\uff08]{0,1}\d{2,4}[-)\uff09]{0,1}\d{2,4}-{0,1}\d{3,4}'
で、いけるんじゃね? -> ダメ。
\
でエスケープしたりいろいろ試したけど、結局unicodedata.normalize('NFKC', hoge)
で半角にして処理することにした。
最終的なコード(正規表現部分のみ)
pattern = r'[(]{0,1}[0-9]{2,4}[)-(]{0,1}[0-9]{2,4}[)-]{0,1}[0-9]{3,4}'
-
\d
は[0-9]に変更。\d
は知ってればわかるけど一見何なのかわからないので。 - 00(0000)0000に対応。
そうするとraise error, v # invalid expression
。。。どこがエラーなのか?
pattern = r'[\(]{0,1}[0-9]{2,4}[\)\-\(]{0,1}[0-9]{2,4}[\)\-]{0,1}[0-9]{3,4}'
[]内の), -, (にバックスラッシュを入れて解決。
ダイヤル(0120)000-000 電話(03)0000-0000
-> [u'(0120)000-000', u'(03)0000-0000']
めでたしめでたし。
おまけ: ループを回すときはコンパイルしておく
pattern = re.compile(r'hogehoge')
for i in iter:
# do something
tel_number = pattern.findall(raw_html)
こうしておくと速いらしい。