【Python】正規表現グルーピングを使用して郵便番号を”-”区切りで取得してみる

検索対象パターン

今回検索対象パターンとなる文字列は
123-4567のような
3桁の数字 – 4桁の数字で構築された文字列です。
また今回は
3桁の数字、4桁の数字を分けて取得したいと思います。
またそういう場合に使用するのがグルーピングです。

使用するモジュール

・re

正規表現で郵便番号検索

Pythonで正規表現を使用し文字列検索を行う場合は下記の手順で行います。

1.Regexオブジェクトの生成
2.Matchオブジェクトの生成
3.マッチした結果を取得

郵便番号検索の正規表現

まず検索文字列をつくります。
3桁の数字 – 4桁の数字を正規表現で表す場合
\d\d\d-\d\d\d\d
短縮して
\d{3}-\d{4}
で表現できます。

グルーピング

グルーピングする場合は()で各グループを括ります。
今回は3桁の数字、4桁の数字で分けたいので
(\d{3})-(\d{4})
となります

Regexオブジェクトの生成

reモジュールのcompile関数を使ってRegexオブジェクトを作成します。

#郵便番号検索を行うRegexオブジェクト
post_number_rx=re.compile(r"(\d{3})-(\d{4})")

Matchオブジェクトの生成

Regexオブジェクトのsearchメソッドを使って文字列の中から郵便番号を検索し、
検索結果のMatchオブジェクトを取得します。

#Regexオブジェクトで検索しMatchオブジェクトを取得する
post_number_mo = post_number_rx.search("testnumber=123-7890")

マッチした結果を取得

グループごとに取得

Matchオブジェクトのgroupメソッドにグループ番号を指定して取得します。

#1番目の3桁の数字を取得
post_number_mo.group(1)
#結果は123
#2番目の4桁の数字を取得
post_number_mo.group(2)
#結果は7890

グループ全てを一括で取得

指定されたグループをすべて一括で取得する場合はMatchオブジェクトのgroupsメソッドを使用します。
結果はtupleです。

#グループ考慮せず取得
post_number_mo.groups()
#結果は('123', '7890')

グループ考慮せず取得

グループを考慮せず検索結果全体を取得したい場合はグループ番号を指定せずgroupメソッドを呼びます

#グループ考慮せず取得
post_number_mo.group()
#結果は123-7890

(例外)検索文字列内に複数のマッチする結果がある場合

正規表現を使用してRegexオブジェクトのsearchメソッドで検索すると、
検索文字列内で最初にヒットした文字列がMatchオブジェクトとして返されます。
もし複数取得したい場合はRegexオブジェクトのfindallメソッドを使用します。
ただし、このときRegexオブジェクトはMatchオブジェクトを返さず、検索した結果の文字列リストを返します。
グループが指定されている場合はtupleリストが返されます。

post_number_rx.findall("testnumber=123-7890,666-7777,333-8888")
#結果は[('123', '7890'), ('666', '7777'), ('333', '8888')]

サンプルコード

import re

REGEX_POST_NUMBER=r"(\d{3})-(\d{4})"

def search_post_number(search_str):
    #郵便番号番号のRegexオブジェクトをつくる
    post_number_rx=re.compile(REGEX_POST_NUMBER)
    #郵便番号番号のRegexで文字列を検索しMatchオブジェクトを取得
    post_number_mo =  post_number_rx.search(search_str)
    
    
    #groupsで対象グループ全て表示
    print("groups():" + str(post_number_mo.groups()))
    
    #groupにグループ番号を指定して指定グループを表示
    print("group(1):" + post_number_mo.group(1))
    print("group(2):" + post_number_mo.group(2))

    #グループを考慮せず表示
    print("group():" + post_number_mo.group())
    
    
    #郵便番号番号のRegexで検索結果全て取得
    result = post_number_rx.findall(search_str)
    print("findall:" + str(result))

    
    

if __name__ == "__main__":
    search_str = "testnumber=123-7890,666-7777,333-8888"
    search_post_number(search_str)

あわせて読みたい