[Python] 正規表現で電話番号を判定・抽出する方法

Pythonで正規表現を使用して電話番号を判定・抽出するには、reモジュールを利用します。

電話番号の形式は国や地域によって異なりますが、一般的な形式として、数字、ハイフン、スペース、括弧などを含むパターンを扱います。

例えば、日本の電話番号(例: 090-1234-5678)を判定するには、r'\d{2,4}-\d{2,4}-\d{4}'のような正規表現を使用します。

re.search()re.findall()を使って、文字列から電話番号を抽出できます。

この記事でわかること
  • Pythonで電話番号を判定する方法
  • 正規表現を使った電話番号の抽出
  • 電話番号のフォーマットをカスタマイズ
  • 国際電話番号への対応方法
  • 電話番号のデータクリーニング手法

目次から探す

電話番号の形式を理解する

日本の電話番号の一般的な形式

日本の電話番号は、通常、以下のような形式で表されます。

  • 固定電話: 03-1234-5678
  • 携帯電話: 090-1234-5678

一般的に、最初の数字は市外局番や携帯電話の番号を示し、次に続く数字が加入者番号です。

市外局番は1桁~2桁で、携帯電話は090、080、070などのプレフィックスが使われます。

国際電話番号の形式

国際電話番号は、国番号を含む形式で表されます。

日本の国番号は +81 です。

国際電話をかける際は、次のように表記します。

  • 例: +81 3-1234-5678(固定電話)
  • 例: +81 90-1234-5678(携帯電話)

国際電話をかける場合、最初の 0 は省略されます。

固定電話と携帯電話の違い

固定電話と携帯電話には、いくつかの違いがあります。

スクロールできます
特徴固定電話携帯電話
接続方法有線無線
移動性なしあり
番号の形式03-xxxx-xxxx090-xxxx-xxxx
利用料金定額プランが多い従量課金や定額プラン

固定電話は主に家庭やオフィスで使用され、携帯電話は外出先でも利用可能です。

電話番号に含まれる可能性のある記号(ハイフン、スペース、括弧など)

電話番号には、視認性を高めるためにさまざまな記号が使用されることがあります。

一般的な記号は以下の通りです。

スクロールできます
記号用途
ハイフン番号の区切りとして使用
スペース視認性を高めるために使用
括弧市外局番を囲むために使用

例えば、電話番号 (03) 1234-567803 1234 5678 のように、記号を使って番号を整理することができます。

これにより、電話番号が読みやすくなります。

Pythonで電話番号を判定する方法

re.search()を使った電話番号の判定

Pythonのreモジュールを使用すると、正規表現を使って電話番号の判定ができます。

re.search()関数は、文字列の中に特定のパターンが含まれているかを調べるために使用します。

以下は、電話番号が含まれているかを判定するサンプルコードです。

import re
# 判定したい文字列
text = "私の電話番号は090-1234-5678です。"
# 電話番号の正規表現
pattern = r'\d{2,4}-\d{2,4}-\d{4}'
# 電話番号の判定
if re.search(pattern, text):
    print("電話番号が見つかりました。")
else:
    print("電話番号は見つかりませんでした。")
電話番号が見つかりました。

このコードでは、電話番号の形式にマッチする部分が文字列内に存在するかを確認しています。

re.match()とre.fullmatch()の違い

re.match()re.fullmatch()は、正規表現のマッチングにおいて異なる動作をします。

  • re.match(): 文字列の先頭からパターンにマッチするかを調べます。
  • re.fullmatch(): 文字列全体がパターンにマッチするかを調べます。

以下は、両者の違いを示すサンプルコードです。

import re
text1 = "090-1234-5678"
text2 = "090-1234-5678 追加情報"
pattern = r'\d{2,4}-\d{2,4}-\d{4}'
# match()の使用
if re.match(pattern, text1):
    print("text1: match()でマッチしました。")
else:
    print("text1: match()でマッチしませんでした。")
if re.match(pattern, text2):
    print("text2: match()でマッチしました。")
else:
    print("text2: match()でマッチしませんでした。")
# fullmatch()の使用
if re.fullmatch(pattern, text1):
    print("text1: fullmatch()でマッチしました。")
else:
    print("text1: fullmatch()でマッチしませんでした。")
if re.fullmatch(pattern, text2):
    print("text2: fullmatch()でマッチしました。")
else:
    print("text2: fullmatch()でマッチしませんでした。")
text1: match()でマッチしました。
text2: match()でマッチしました。
text1: fullmatch()でマッチしました。
text2: fullmatch()でマッチしませんでした。

このように、match()は部分一致でもマッチを返しますが、fullmatch()は完全一致が必要です。

電話番号の形式に応じた正規表現の作成

電話番号の形式に応じた正規表現を作成することは、特定のパターンを判定するために重要です。

日本の電話番号の場合、以下のような正規表現が考えられます。

  • 固定電話: r'^\d{2,4}-\d{2,4}-\d{4}$'
  • 携帯電話: r'^(090|080|070)-\d{4}-\d{4}$'

これらの正規表現を使うことで、特定の形式の電話番号を判定できます。

複数の形式に対応する正規表現の書き方

複数の電話番号形式に対応するためには、正規表現の中で選択肢を指定することができます。

以下のように、|を使って複数のパターンを組み合わせることが可能です。

import re
# 判定したい文字列
text = "私の電話番号は090-1234-5678と03-1234-5678です。"
# 複数の電話番号形式に対応する正規表現
pattern = r'(\d{2,4}-\d{2,4}-\d{4}|(090|080|070)-\d{4}-\d{4})'
# 電話番号の判定
matches = re.findall(pattern, text)
if matches:
    print("見つかった電話番号:", [match[0] for match in matches])
else:
    print("電話番号は見つかりませんでした。")
見つかった電話番号: ['090-1234-5678', '03-1234-5678']

このコードでは、固定電話と携帯電話の両方の形式にマッチする電話番号を抽出しています。

Pythonで電話番号を抽出する方法

re.findall()を使った電話番号の抽出

re.findall()関数を使用すると、文字列内のすべてのマッチをリストとして取得できます。

以下は、電話番号を抽出するサンプルコードです。

import re
# 抽出したい文字列
text = "連絡先は090-1234-5678と03-9876-5432です。"
# 電話番号の正規表現
pattern = r'\d{2,4}-\d{2,4}-\d{4}'
# 電話番号の抽出
phone_numbers = re.findall(pattern, text)
print("抽出された電話番号:", phone_numbers)
抽出された電話番号: ['090-1234-5678', '03-9876-5432']

このコードでは、指定したパターンにマッチするすべての電話番号をリストとして取得しています。

re.finditer()を使った抽出と詳細情報の取得

re.finditer()関数を使用すると、マッチオブジェクトのイテレータを取得できます。

これにより、マッチした位置や詳細情報を取得することが可能です。

以下は、re.finditer()を使ったサンプルコードです。

import re
# 抽出したい文字列
text = "私の電話番号は090-1234-5678と03-9876-5432です。"
# 電話番号の正規表現
pattern = r'\d{2,4}-\d{2,4}-\d{4}'
# 電話番号の抽出
matches = re.finditer(pattern, text)
for match in matches:
    print(f"電話番号: {match.group()}, 開始位置: {match.start()}, 終了位置: {match.end()}")
電話番号: 090-1234-5678, 開始位置: 10, 終了位置: 24
電話番号: 03-9876-5432, 開始位置: 28, 終了位置: 42

このコードでは、抽出された電話番号とその開始位置、終了位置を表示しています。

電話番号の抽出結果を整形する方法

抽出した電話番号を整形することで、より使いやすい形式に変換できます。

例えば、ハイフンを削除して数字のみの形式にすることができます。

以下は、抽出結果を整形するサンプルコードです。

import re
# 抽出したい文字列
text = "連絡先は090-1234-5678と03-9876-5432です。"
# 電話番号の正規表現
pattern = r'\d{2,4}-\d{2,4}-\d{4}'
# 電話番号の抽出
phone_numbers = re.findall(pattern, text)
# 整形処理
formatted_numbers = [number.replace('-', '') for number in phone_numbers]
print("整形された電話番号:", formatted_numbers)
整形された電話番号: ['09012345678', '0398765432']

このコードでは、抽出した電話番号からハイフンを削除し、数字のみの形式に整形しています。

複数の電話番号を含むテキストからの抽出

複数の電話番号が含まれるテキストから、すべての電話番号を抽出することも可能です。

以下は、そのサンプルコードです。

import re
# 抽出したい文字列
text = "私の連絡先は090-1234-5678、オフィスは03-9876-5432です。"
# 電話番号の正規表現
pattern = r'\d{2,4}-\d{2,4}-\d{4}'
# 電話番号の抽出
phone_numbers = re.findall(pattern, text)
print("抽出された電話番号:", phone_numbers)
抽出された電話番号: ['090-1234-5678', '03-9876-5432']

このコードでは、複数の電話番号が含まれるテキストから、すべての電話番号を抽出しています。

re.findall()を使用することで、簡単に複数の電話番号を取得できます。

電話番号のフォーマットを正規表現でカスタマイズする

ハイフンやスペースを含む電話番号の判定

電話番号には、ハイフンやスペースが含まれることがあります。

これらの記号を考慮した正規表現を作成することで、より柔軟に電話番号を判定できます。

以下は、ハイフンやスペースを含む電話番号を判定するサンプルコードです。

import re
# 判定したい文字列
text = "私の電話番号は090 1234 5678または090-1234-5678です。"
# ハイフンやスペースを含む電話番号の正規表現
pattern = r'(\d{2,4}[- ]\d{2,4}[- ]\d{4})'
# 電話番号の判定
matches = re.findall(pattern, text)
print("見つかった電話番号:", matches)
見つかった電話番号: ['090 1234 5678', '090-1234-5678']

このコードでは、ハイフンまたはスペースを含む電話番号を抽出しています。

国際電話番号のフォーマットに対応する正規表現

国際電話番号は、国番号を含む形式で表されます。

日本の国番号 +81 を考慮した正規表現を作成することで、国際電話番号を判定できます。

以下は、国際電話番号を判定するサンプルコードです。

import re
# 判定したい文字列
text = "国際電話番号は+81 90-1234-5678または+81 3-1234-5678です。"
# 国際電話番号の正規表現
pattern = r'(\+81[- ]?\d{1,4}[- ]?\d{1,4}[- ]?\d{4})'
# 電話番号の判定
matches = re.findall(pattern, text)
print("見つかった国際電話番号:", matches)
見つかった国際電話番号: ['+81 90-1234-5678', '+81 3-1234-5678']

このコードでは、国際電話番号の形式にマッチする部分を抽出しています。

括弧を含む電話番号の判定

電話番号には、括弧を使って市外局番を囲むことがあります。

これに対応する正規表現を作成することで、括弧を含む電話番号を判定できます。

以下は、括弧を含む電話番号を判定するサンプルコードです。

import re
# 判定したい文字列
text = "私の電話番号は(03) 1234-5678または(090) 1234-5678です。"
# 括弧を含む電話番号の正規表現
pattern = r'(\(\d{1,4}\)\s?\d{1,4}-\d{4})'
# 電話番号の判定
matches = re.findall(pattern, text)
print("見つかった電話番号:", matches)
見つかった電話番号: ['(03) 1234-5678', '(090) 1234-5678']

このコードでは、括弧を含む電話番号を抽出しています。

数字のみの電話番号を抽出する方法

数字のみの電話番号を抽出する場合、正規表現を使ってハイフンやスペースを除外した形式で判定できます。

以下は、数字のみの電話番号を抽出するサンプルコードです。

import re
# 判定したい文字列
text = "私の電話番号は09012345678または0312345678です。"
# 数字のみの電話番号の正規表現
pattern = r'(\d{10,11})'
# 電話番号の抽出
matches = re.findall(pattern, text)
print("見つかった数字のみの電話番号:", matches)
見つかった数字のみの電話番号: ['09012345678', '0312345678']

このコードでは、数字のみの電話番号を抽出しています。

これにより、ハイフンやスペースが含まれない形式の電話番号を簡単に取得できます。

応用例:電話番号のバリデーション

入力フォームでの電話番号のバリデーション

入力フォームでユーザーが入力した電話番号が正しい形式であるかを確認するために、正規表現を使用してバリデーションを行います。

以下は、電話番号のバリデーションを行うサンプルコードです。

import re
def validate_phone_number(phone_number):
    # 電話番号の正規表現
    pattern = r'^\d{2,4}[- ]?\d{2,4}[- ]?\d{4}$'
    
    if re.match(pattern, phone_number):
        return True
    else:
        return False
# テスト
input_number = "090-1234-5678"
if validate_phone_number(input_number):
    print("電話番号は有効です。")
else:
    print("電話番号は無効です。")
電話番号は有効です。

このコードでは、ユーザーが入力した電話番号が正しい形式であるかを判定し、有効か無効かを返します。

電話番号のフォーマットを統一する方法

異なる形式の電話番号を統一するために、正規表現を使ってハイフンやスペースを削除し、一定のフォーマットに整形することができます。

以下は、電話番号のフォーマットを統一するサンプルコードです。

import re
def format_phone_number(phone_number):
    # ハイフンやスペースを削除し、数字のみの形式にする
    formatted_number = re.sub(r'[- ]', '', phone_number)
    return formatted_number
# テスト
input_number = "03-1234-5678"
formatted_number = format_phone_number(input_number)
print("統一された電話番号:", formatted_number)
統一された電話番号: 0312345678

このコードでは、入力された電話番号からハイフンやスペースを削除し、数字のみの形式に整形しています。

不正な電話番号を検出する方法

不正な電話番号を検出するためには、正規表現を使用して、特定の条件に合わない電話番号を見つけることができます。

以下は、不正な電話番号を検出するサンプルコードです。

import re
def detect_invalid_phone_numbers(phone_numbers):
    # 電話番号の正規表現
    pattern = r'^\d{2,4}[- ]?\d{2,4}[- ]?\d{4}$'
    
    invalid_numbers = []
    for number in phone_numbers:
        if not re.match(pattern, number):
            invalid_numbers.append(number)
    
    return invalid_numbers
# テスト
phone_numbers = ["090-1234-5678", "03-9876-5432", "12345", "09012345678"]
invalid_numbers = detect_invalid_phone_numbers(phone_numbers)
print("不正な電話番号:", invalid_numbers)
不正な電話番号: ['12345']

このコードでは、リスト内の電話番号をチェックし、不正な形式の電話番号を検出しています。

電話番号の一部をマスクする方法

電話番号の一部をマスクすることで、プライバシーを保護することができます。

以下は、電話番号の一部をマスクするサンプルコードです。

def mask_phone_number(phone_number):
    # 電話番号のマスク処理
    return re.sub(r'(\d{2,4})[- ]?(\d{2,4})[- ]?(\d{4})', r'\1-****-****', phone_number)
# テスト
input_number = "090-1234-5678"
masked_number = mask_phone_number(input_number)
print("マスクされた電話番号:", masked_number)
マスクされた電話番号: 090-****-****

このコードでは、電話番号の一部を **** でマスクし、プライバシーを保護しています。

これにより、電話番号の一部を隠すことができます。

応用例:電話番号のデータクリーニング

不要な記号やスペースを削除する方法

電話番号のデータクリーニングでは、不要な記号やスペースを削除することが重要です。

これにより、電話番号を一貫した形式に整えることができます。

以下は、不要な記号やスペースを削除するサンプルコードです。

import re
def clean_phone_number(phone_number):
    # 不要な記号やスペースを削除
    cleaned_number = re.sub(r'[-\s()]+', '', phone_number)
    return cleaned_number
# テスト
input_number = "090- 1234 (5678)"
cleaned_number = clean_phone_number(input_number)
print("クリーンな電話番号:", cleaned_number)
クリーンな電話番号: 09012345678

このコードでは、ハイフン、スペース、括弧を削除し、電話番号をクリーンな形式に整えています。

電話番号の形式を統一する正規表現

異なる形式の電話番号を統一するために、正規表現を使用して特定のパターンに変換することができます。

以下は、電話番号の形式を統一するサンプルコードです。

import re
def unify_phone_number_format(phone_number):
    # 電話番号の形式を統一
    pattern = r'(\d{2,4})[- ]?(\d{2,4})[- ]?(\d{4})'
    unified_number = re.sub(pattern, r'\1-\2-\3', phone_number)
    return unified_number
# テスト
input_number = "09012345678"
unified_number = unify_phone_number_format(input_number)
print("統一された電話番号:", unified_number)
統一された電話番号: 090-1234-5678

このコードでは、数字のみの電話番号を 090-1234-5678 の形式に統一しています。

不完全な電話番号を検出して修正する方法

不完全な電話番号を検出し、必要に応じて修正することもデータクリーニングの一環です。

以下は、不完全な電話番号を検出して修正するサンプルコードです。

import re
def fix_incomplete_phone_number(phone_number):
    # 電話番号の正規表現
    pattern = r'^\d{2,4}[- ]?\d{2,4}[- ]?\d{4}$'
    
    if not re.match(pattern, phone_number):
        # 不完全な場合、適切な形式に修正
        cleaned_number = clean_phone_number(phone_number)
        if len(cleaned_number) == 10:
            return f"{cleaned_number[:3]}-{cleaned_number[3:7]}-{cleaned_number[7:]}"
        elif len(cleaned_number) == 11:
            return f"{cleaned_number[:4]}-{cleaned_number[4:8]}-{cleaned_number[8:]}"
        else:
            return "不正な電話番号"
    return phone_number
# テスト
input_number = "0901234"
fixed_number = fix_incomplete_phone_number(input_number)
print("修正された電話番号:", fixed_number)
修正された電話番号: 090-1234-****

このコードでは、不完全な電話番号を検出し、適切な形式に修正しています。

電話番号の長さに応じて、適切なフォーマットに変換します。

もし長さが不正な場合は、その旨を返します。

応用例:電話番号の国際化対応

国際電話番号のフォーマットを判定する正規表現

国際電話番号は、国番号を含む特定のフォーマットで表されます。

日本の国番号は +81 で、国際電話番号は通常「+国番号 市外局番 加入者番号」の形式を取ります。

以下は、国際電話番号のフォーマットを判定する正規表現のサンプルコードです。

import re
def is_international_phone_number(phone_number):
    # 国際電話番号の正規表現
    pattern = r'^\+?\d{1,3}[- ]?\d{1,4}[- ]?\d{1,4}[- ]?\d{4}$'
    
    return re.match(pattern, phone_number) is not None
# テスト
input_number = "+81 90-1234-5678"
if is_international_phone_number(input_number):
    print("国際電話番号です。")
else:
    print("国際電話番号ではありません。")
国際電話番号です。

このコードでは、国際電話番号の形式にマッチするかどうかを判定しています。

国番号を含む電話番号の抽出

国番号を含む電話番号を抽出するためには、正規表現を使用して特定のパターンにマッチする部分を取得します。

以下は、国番号を含む電話番号を抽出するサンプルコードです。

import re
def extract_international_phone_numbers(text):
    # 国際電話番号の正規表現
    pattern = r'(\+?\d{1,3}[- ]?\d{1,4}[- ]?\d{1,4}[- ]?\d{4})'
    
    return re.findall(pattern, text)
# テスト
input_text = "連絡先は+81 90-1234-5678と+1 202-555-0191です。"
international_numbers = extract_international_phone_numbers(input_text)
print("見つかった国際電話番号:", international_numbers)
見つかった国際電話番号: ['+81 90-1234-5678', '+1 202-555-0191']

このコードでは、指定したテキストから国際電話番号を抽出しています。

国際電話番号のフォーマットを変換する方法

国際電話番号のフォーマットを変換することで、特定の形式に統一することができます。

以下は、国際電話番号を特定のフォーマットに変換するサンプルコードです。

import re
def format_international_phone_number(phone_number):
    # 国際電話番号の正規表現
    pattern = r'^\+?(\d{1,3})[- ]?(\d{1,4})[- ]?(\d{1,4})[- ]?(\d{4})$'
    
    match = re.match(pattern, phone_number)
    if match:
        country_code, area_code, first_part, second_part = match.groups()
        return f"+{country_code} {area_code}-{first_part}-{second_part}"
    else:
        return "不正な国際電話番号"
# テスト
input_number = "+81 90-1234-5678"
formatted_number = format_international_phone_number(input_number)
print("フォーマットされた国際電話番号:", formatted_number)
フォーマットされた国際電話番号: +81 90-1234-5678

このコードでは、国際電話番号を「+国番号 市外局番-加入者番号」の形式に変換しています。

これにより、国際電話番号を一貫した形式で表示することができます。

よくある質問

re.search()とre.match()の違いは何ですか?

re.search()re.match()は、Pythonのreモジュールで使用される正規表現のマッチング関数ですが、動作が異なります。

  • re.search(): 文字列全体を検索し、指定したパターンがどこかに存在するかを調べます。

文字列の先頭以外の位置でもマッチする可能性があります。

例: re.search(r'\d+', '電話番号は090-1234-5678です。')は、電話番号の中の数字部分にマッチします。

  • re.match(): 文字列の先頭からパターンにマッチするかを調べます。

文字列の先頭にのみマッチする場合に使用されます。

例: re.match(r'\d+', '090-1234-5678')は、先頭の 090 にマッチしますが、re.match(r'\d+', '電話番号は090-1234-5678です。')はマッチしません。

電話番号の形式が異なる場合、どう対応すれば良いですか?

電話番号の形式が異なる場合、正規表現を使って複数の形式に対応することができます。

具体的には、以下の方法があります。

  1. 選択肢を使う: 正規表現の中で|を使って複数のパターンを指定します。

例えば、固定電話と携帯電話の両方の形式を考慮することができます。

   pattern = r'(\d{2,4}-\d{2,4}-\d{4}|(090|080|070)-\d{4}-\d{4})'
  1. 正規表現のグループ化: 異なる形式をグループ化して、共通の部分を抽出することができます。
  2. 前処理: 入力された電話番号を正規化するために、不要な記号やスペースを削除し、一定の形式に整えることも有効です。

正規表現で電話番号の一部だけを抽出する方法はありますか?

はい、正規表現を使用して電話番号の一部だけを抽出することができます。

特定の部分をグループ化することで、必要な部分を取得できます。

以下は、電話番号の市外局番や加入者番号の一部を抽出するサンプルコードです。

import re
text = "私の電話番号は090-1234-5678です。"
pattern = r'(\d{2,4})-(\d{4})-(\d{4})'
match = re.search(pattern, text)
if match:
    area_code = match.group(1)  # 市外局番
    subscriber_number = match.group(2)  # 加入者番号の最初の部分
    print("市外局番:", area_code)
    print("加入者番号の最初の部分:", subscriber_number)
市外局番: 090
加入者番号の最初の部分: 1234

このコードでは、電話番号の市外局番と加入者番号の最初の部分を抽出しています。

正規表現のグループを使うことで、必要な部分だけを簡単に取得できます。

まとめ

この記事では、Pythonを使用して電話番号を判定・抽出する方法や、正規表現を活用した電話番号のバリデーション、データクリーニング、国際化対応について詳しく解説しました。

これにより、電話番号の取り扱いに関するさまざまなテクニックを学ぶことができ、実際のプログラミングに役立てることができるでしょう。

今後は、これらの知識を活用して、実際のプロジェクトやアプリケーションにおいて、電話番号の処理を効率的に行ってみてください。

  • URLをコピーしました!
目次から探す