2022/05/10

[Python]ハイフンなし電話番号からハイフン付きに復元

python

概要

ハイフンなしの日本の電話番号をハイフン付きにする必要があったので、実装しました。

こちらの方の記事を大いに参考にさせていただきました。
Rubyで作られていたので、pythonに書き換えました。

総務省のデータに基づいているようです。

Parserの実装

以下のような形になりました。

from typing import List

__MAP = {
    "050": 4,  # IP電話
    "070": 4,  # 携帯電話/PHS
    "080": 4,  # 携帯電話
    "090": 4,  # 携帯電話
    "020": 3,  # その他
    "0120": 3,  # その他
    "0800": 3,  # その他
    "0570": 3,  # その他
    "0990": 3,  # その他
    # 固定電話
    "011": 3,
    "0123": 2,
    "0124": 2,
    "0125": 2,
    "0126": 2,
    "01267": 1,
    "0133": 2,
    "0134": 2,
    "0135": 2,
    "0136": 2,
    "01372": 1,
    "01374": 1,
    "0137": 2,
    "01377": 1,
    "0138": 2,
    "01392": 1,
    "0139": 2,
    "01397": 1,
    "01398": 1,
    "0142": 2,
    "0143": 2,
    "0144": 2,
    "0145": 2,
    "01456": 1,
    "01457": 1,
    "0146": 2,
    "01466": 1,
    "0152": 2,
    "0153": 2,
    "0154": 2,
    "01547": 1,
    "0155": 2,
    "015": 3,
    "01558": 1,
    "01564": 1,
    "0156": 2,
    "0157": 2,
    "01586": 1,
    "01587": 1,
    "0158": 2,
    "0162": 2,
    "01632": 1,
    "01634": 1,
    "01635": 1,
    "0163": 2,
    "0164": 2,
    "01648": 1,
    "0165": 2,
    "01654": 1,
    "01655": 1,
    "01656": 1,
    "01658": 1,
    "0166": 2,
    "0167": 2,
    "0172": 2,
    "0173": 2,
    "0174": 2,
    "0175": 2,
    "0176": 2,
    "017": 3,
    "0178": 2,
    "0179": 2,
    "0182": 2,
    "0183": 2,
    "0184": 2,
    "0185": 2,
    "0186": 2,
    "0187": 2,
    "018": 3,
    "0191": 2,
    "0192": 2,
    "0193": 2,
    "0194": 2,
    "0195": 2,
    "019": 3,
    "0197": 2,
    "0198": 2,
    "022": 3,
    "0220": 2,
    "0223": 2,
    "0224": 2,
    "0225": 2,
    "0226": 2,
    "0228": 2,
    "0229": 2,
    "0233": 2,
    "0234": 2,
    "0235": 2,
    "023": 3,
    "0237": 2,
    "0238": 2,
    "0240": 2,
    "0241": 2,
    "0242": 2,
    "0243": 2,
    "0244": 2,
    "0246": 2,
    "0247": 2,
    "0248": 2,
    "024": 3,
    "0250": 2,
    "0254": 2,
    "0255": 2,
    "0256": 2,
    "0257": 2,
    "025": 3,
    "0258": 2,
    "0259": 2,
    "0260": 2,
    "0261": 2,
    "026": 3,
    "0263": 2,
    "0264": 2,
    "0265": 2,
    "0266": 2,
    "0267": 2,
    "0268": 2,
    "0269": 2,
    "0270": 2,
    "027": 3,
    "0274": 2,
    "0276": 2,
    "0277": 2,
    "0278": 2,
    "0279": 2,
    "0280": 2,
    "0282": 2,
    "0283": 2,
    "0284": 2,
    "0285": 2,
    "028": 3,
    "0287": 2,
    "0288": 2,
    "0289": 2,
    "0291": 2,
    "0293": 2,
    "0294": 2,
    "0295": 2,
    "0296": 2,
    "0297": 2,
    "029": 3,
    "0299": 2,
    "03": 4,
    "0422": 2,
    "0428": 2,
    "042": 3,
    "043": 3,
    "0436": 2,
    "0438": 2,
    "0439": 2,
    "044": 3,
    "045": 3,
    "0460": 2,
    "0463": 2,
    "0465": 2,
    "0466": 2,
    "0467": 2,
    "046": 3,
    "0470": 2,
    "04": 4,
    "047": 3,
    "0475": 2,
    "0476": 2,
    "0478": 2,
    "0479": 2,
    "0480": 2,
    "048": 3,
    "049": 3,
    "0493": 2,
    "0494": 2,
    "0495": 2,
    "04992": 1,
    "04994": 1,
    "04996": 1,
    "04998": 1,
    "052": 3,
    "053": 3,
    "0531": 2,
    "0532": 2,
    "0533": 2,
    "0536": 2,
    "0537": 2,
    "0538": 2,
    "0539": 2,
    "054": 3,
    "0544": 2,
    "0545": 2,
    "0547": 2,
    "0548": 2,
    "0550": 2,
    "0551": 2,
    "0553": 2,
    "0554": 2,
    "0555": 2,
    "0556": 2,
    "0557": 2,
    "0558": 2,
    "055": 3,
    "0561": 2,
    "0562": 2,
    "0563": 2,
    "0564": 2,
    "0565": 2,
    "0566": 2,
    "0567": 2,
    "0568": 2,
    "0569": 2,
    "0572": 2,
    "0573": 2,
    "0574": 2,
    "0575": 2,
    "0576": 2,
    "05769": 1,
    "0577": 2,
    "0578": 2,
    "058": 3,
    "0581": 2,
    "0584": 2,
    "0585": 2,
    "0586": 2,
    "0587": 2,
    "059": 3,
    "0594": 2,
    "0595": 2,
    "0596": 2,
    "0597": 2,
    "05979": 1,
    "0598": 2,
    "0599": 2,
    "06": 4,
    "0721": 2,
    "0725": 2,
    "072": 3,
    "073": 3,
    "0735": 2,
    "0736": 2,
    "0737": 2,
    "0738": 2,
    "0739": 2,
    "0740": 2,
    "0742": 2,
    "0743": 2,
    "0744": 2,
    "0745": 2,
    "0746": 2,
    "07468": 1,
    "0747": 2,
    "0748": 2,
    "0749": 2,
    "075": 3,
    "0761": 2,
    "0763": 2,
    "076": 3,
    "0765": 2,
    "0766": 2,
    "0767": 2,
    "0768": 2,
    "0770": 2,
    "0771": 2,
    "0772": 2,
    "0774": 2,
    "077": 3,
    "0776": 2,
    "0778": 2,
    "0779": 2,
    "078": 3,
    "0790": 2,
    "0791": 2,
    "0794": 2,
    "0795": 2,
    "0796": 2,
    "079": 3,
    "0797": 2,
    "0798": 2,
    "0799": 2,
    "0820": 2,
    "0823": 2,
    "082": 3,
    "0824": 2,
    "0826": 2,
    "0827": 2,
    "0829": 2,
    "0833": 2,
    "0834": 2,
    "0835": 2,
    "0836": 2,
    "0837": 2,
    "0838": 2,
    "08387": 1,
    "08388": 1,
    "083": 3,
    "08396": 1,
    "0845": 2,
    "0846": 2,
    "0847": 2,
    "08477": 1,
    "0848": 2,
    "084": 3,
    "08512": 1,
    "08514": 1,
    "0852": 2,
    "0853": 2,
    "0854": 2,
    "0855": 2,
    "0856": 2,
    "0857": 2,
    "0858": 2,
    "0859": 2,
    "0863": 2,
    "0865": 2,
    "0866": 2,
    "0867": 2,
    "0868": 2,
    "0869": 2,
    "086": 3,
    "0875": 2,
    "0877": 2,
    "087": 3,
    "0879": 2,
    "0880": 2,
    "0883": 2,
    "0884": 2,
    "0885": 2,
    "0887": 2,
    "088": 3,
    "0889": 2,
    "0892": 2,
    "0893": 2,
    "0894": 2,
    "0895": 2,
    "0896": 2,
    "0897": 2,
    "0898": 2,
    "089": 3,
    "092": 3,
    "0920": 2,
    "093": 3,
    "0930": 2,
    "0940": 2,
    "0942": 2,
    "0943": 2,
    "0944": 2,
    "0946": 2,
    "0947": 2,
    "0948": 2,
    "0949": 2,
    "09496": 1,
    "0950": 2,
    "0952": 2,
    "0955": 2,
    "0956": 2,
    "0957": 2,
    "095": 3,
    "0959": 2,
    "096": 3,
    "0964": 2,
    "0965": 2,
    "0966": 2,
    "0967": 2,
    "0968": 2,
    "0969": 2,
    "0972": 2,
    "0973": 2,
    "0974": 2,
    "097": 3,
    "0977": 2,
    "0978": 2,
    "0979": 2,
    "098": 3,
    "09802": 1,
    "0980": 2,
    "0982": 2,
    "0983": 2,
    "0984": 2,
    "0985": 2,
    "0986": 2,
    "0987": 2,
    "09912": 1,
    "09913": 1,
    "0993": 2,
    "099": 3,
    "0994": 2,
    "0995": 2,
    "0996": 2,
    "09969": 1,
    "0997": 2,
}

__MAP_BY_LENGTH = {}

for k in __MAP:
    v = __MAP.get(k)
    key = len(k)
    value = __MAP_BY_LENGTH.get(key)
    if value:
        value[k] = v
    else:
        value = {
            k: v,
        }
    __MAP_BY_LENGTH[key] = value


def split_phone_number(s: str) -> List[str]:
    length_list = list(__MAP_BY_LENGTH.keys())
    length_list.sort(reverse=True)
    for prefix_len in length_list:
        definitions = __MAP_BY_LENGTH[prefix_len]
        prefix = s[0:prefix_len]
        if prefix in definitions.keys():
            len2 = definitions.get(prefix)
            return [prefix, s[prefix_len:(prefix_len+len2)], s[(prefix_len+len2):]]
    return [s]

使い方

使い方は以下のような感じ

value = "0300010002"
phone_number_with_hyphen = "-".join(split_phone_number(s=value))
"03-0001-0002"

以上です。