Python module - phonenumbers 電話號碼格式驗證
Posted on Sep 29, 2018 in Python 模組/套件推薦 by Amo Chen ‐ 2 min read
如果 Java, C++, Javascript 開發者想驗證各個不同國家電話號碼的格式與正確性的話,可以利用 Google 所開源的 libphonenumber ,著實省去很多苦工。如果是使用 Python 的開發者則可以安裝模組 phonenumbers 做到一樣的事情,該 module 是由 daviddrysdale
佛心將 Google libphonenumbers 移植到 Python 供大家使用,我每次使用時都心懷感激!
本文將介紹:
- E.164 電話號碼格式
- 用 phonenumbers 驗證電話號碼
- 用 phonenumbers 擷取電話號碼資訊
本文環境
- Python 3.6.5
- phonenumbers 8.9.14
如何安裝 phonenumbers:
$ pip install phonenumbers
E.164 電話號碼格式
使用 phonenumbers 之前必須先認識 E.164 格式。
E.164 格式是由 ITU Telecommunication Standardization Sector (ITU-T) 所推崇的國際電話號碼標準,其格式至少分為 2 個部分 國碼(country code)
+ 用戶號碼(subscriber number)
,且必須為 +
加號開頭,所以一支 E.164 格式的電話號碼會像這樣:
+[國碼][用戶號碼]
這也就是為什麼打國際電話要輸入 +
加號的原因。
此外, E.164 也有提供 optional 的一些格式選項,譬如區碼(area code)。舉例來說,我們輸入台灣常見手機號碼時都會用 0 開頭,例如 0912000000
中的 0 是台灣專用的區碼,在播打國際電話時都不需要輸入,所以 0912000000
再加上國碼 886 的話,用 E.164 格式表示的話,以下 2 種都是正確的:
- +886912000000
- +8860912000000
以上就是簡單的 E.164 格式科普介紹。
用 phonenumbers 驗證電話號碼
如果要驗證一支電話號碼是否正確,可以先使用 phonenumbers.parse
函式,參數必須是 E.164 格式的電話號碼,如果電話號碼格式有錯的話,就會觸發 NumberParseException
:
>>> import phonenumbers
>>> phonenumbers.parse('+8860912000000')
PhoneNumber(country_code=886, national_number=912000000, extension=None, italian_leading_zero=None, number_of_leading_zeros=None, country_code_source=0, preferred_domestic_carrier_code=None)
>>>
>>>
>>> phonenumbers.parse('123456789')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "~/anaconda3/lib/python3.6/site-packages/phonenumbers/phonenumberutil.py", line 2807, in parse
"Missing or invalid default region.")
phonenumbers.phonenumberutil.NumberParseException: (0) Missing or invalid default region.
>>>
>>>
>>> phonenumbers.parse('+88691')
PhoneNumber(country_code=886, national_number=91, extension=None, italian_leading_zero=None, number_of_leading_zeros=None, country_code_source=0, preferred_domestic_carrier_code=None)
上述範例可以發現 phonenumbers.parse
回傳的是一個 PhoneNumber
的 object ,裡面就儲存著電話號碼的相關資訊。同時還可以注意到 phonenumbers.parse('+88691')
竟然沒有觸發任何 NumberParseException
這是由於 phonenumbers.parse
僅先檢查電話格式、是否滿足最小與最大長度,以及電話號碼是否含有合法國碼、區碼等等資訊,如果要進一步驗證電話號碼是否合法,就必須搭配 phonenumbers.is_valid_number
檢查:
>>> p = phonenumbers.parse('+88691')
>>> phonenumbers.is_valid_number(p)
False
>>>
>>>
>>> p = phonenumbers.parse('+886912000000')
>>> phonenumbers.is_valid_number(p)
True
另外,要額外說明的是 phonenumbers.is_valid_number
僅檢查是否為合法的電話號碼,並不代表該電話號碼實際存在或可以撥打成功,請勿誤解。
用 phonenumbers 擷取電話號碼資訊
先前提到 phonenumbers.parse
回傳的是一個 PhoneNumber
的 object ,裡面就儲存著電話號碼的相關資訊,所以可以利用該 object 擷取裡面的資訊。以下提供各種常用的資訊取得法:
取得國碼:
>>> p = phonenumbers.parse('+886912000000')
>>> p.country_code
886
取得國碼名稱:
>>> from phonenumbers import geocoder
>>> geocoder.description_for_number(p, 'en')
Taiwan
取得電信業者名稱(電信資料有因為尚未更新而導致不準確的情況):
>>> from phonenumbers import carrier
>>> carrier.name_for_number(p, 'en')
'Chunghwa Telecom'
把 PhoneNumber
object 以 E.164 格式輸出:
>>> phonenumbers.format_number(p, phonenumbers.PhoneNumberFormat.E164)
'+886912000000'
總結
以上就是 phonenumbers
的簡單介紹,如需要更詳細的使用方法,建議可以閱讀一下 官方文件 或者翻閱其原始碼。
References
https://github.com/googlei18n/libphonenumber
https://github.com/daviddrysdale/python-phonenumbers