毎日ちょっとPython ~ 20日目 ~
土日はいったん休んでみた。けど、別にやったほうがいいと思うのでこれからできる限り休みでもやります。前回はクリップボードをテキストを検索するを読み解くからスタート
クリップボードのテキストを検索するを解剖する
#TODO: クリップボードのテキストを検索する
text = str(pyperclip.paste())
matches = [] # 1.
for groups in phone_regex.findall(text): # 2.
phone_num = '-'.join([groups[1],groups[3],groups[5]])
if groups[8] != '':
phone_num += ' x' + groups[8]
matches.append(phone_num)
for groups in email_regex.findall(text): # 3.
matches.append(groups[0])
findall()メソッドは、検索結果をタプルのリストして返します。正規表現がマッチするたびに1つのタプルが作られ、1つのタプルには正規表現のグループに対応する文字列が格納されています。
検索結果をmatchesのリストに記録していきます。最初は空のリストにして、2回のforループを回します。
先に、メールアドレス側をみましょう。
for groups in email_regex.findall(text): # 3.
matches.append(groups[0])
メールアドレスはグループ0を使って正規表現にマッチした文字列全体をmatchesに追加していきます。
一方、電話番号は単純にグループ0を追加しません。
for groups in phone_regex.findall(text):
phone_num = '-'.join([groups[1],groups[3],groups[5]])
if groups[8] != '':
phone_num += ' x' + groups[8]
matches.append(phone_num)
プログラムは様々な形式の電話番号を見つけ出しますが、追加数るのは一種類の標準フォーマットにしておくほうが便利です。
1,3,5,8グループは、市外局番、3桁の番号、4桁の番号、内線番号に相当します。グループ番号はグループの開きカッコの出現順に数えます。
検索結果を一つにまとめて、クリップボードに移す
これでmatchesに文字列のリストとして、電話番号とメールアドレスを取得できました。
次にこれをクリップボードに貼り付ける作業です。pyperclip.copy()は一つの文字列しか渡せないので(リストのまま渡せないから)join()メソッドを使って一つにまとめます。
#TODO: 検索結果をクリップボードに貼り付ける
if len(matches) > 0:
pyperclip.copy('\n',join(matches))
print('クリップボードにコピーしました:')
print('\n'.join(matches))
else:
print('電話番号やメールアドレスは見つかりませんでした')
こんな感じ。さぁて実行しましょう。
https://nostarch.com/contactus
このページを ctrl - A して、実行してみた。エラーが出た。
line 27, in <module>
if groups[8] != '':
IndexError: tuple index out of range
どうやら、groups[8]がないっていうことで怒られている。ちょっと正規表現に誤りがある可能性があるのでちょっと見返す。4桁の番号が抜けてたので、修正。
phone_regex = re.compile(r'''(
(\d{3}|\(\d{3}\))? #市外局番
(\s|-|\.)? #区切り
(\d{3}) #3桁の番号
(\s|-|\.) #区切り
(\d{4}) #4桁の番号
(\s*(ext|x|ext.)\s*(\d{2,5}))? #内線番号
)''',re.VERBOSE)
んでこれで実行しなおすと、
クリップボードにコピーしました:
800-420-7240
415-863-9900
415-863-9950
o@nostarch.com
a@nostarch.com
c@nostarch.com
o@nostarch.com
でた。なんか結果がおかしい。なぜなら。というところでお時間。次回はこの結果から調査をすることとしよう。