You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

正则与字典实战问题:提取并分组带区号的电话号码

如何提取指定格式电话号码并生成对应字典

需求说明

需要提取文本中的电话号码,规则如下:

  • 区号格式为+加3位数字,区号与号码间可有可无空格;
  • 电话号码本身为7-8位数字;
  • 无区号的7-8位号码需归类到空字符串''对应的键下。

现有代码

def find_phone_numbers(text: str) -> dict:
    pattern = r'\+\w{3} \w{8}|\+\w{11}|\+\w{3} \w{7}|\+\w{10}|\w{8}|\w{7}'
    match = re.findall(pattern, text)
    str1 = " "
    phone_str = str1.join(match)
    phone_dict = {}
    phones = phone_str.split(" ")
    for phone in phones:
        if phone[0] == "+":
            phone0 = phone
    if phone_str[0:4] not in phone_dict.keys():
        phone_dict[phone_str[0:4]] = [phone_str[5:]]
    return phone_dict

预期输出

print(find_phone_numbers("+372 56887364  +37256887364  +33359835647  56887364 +11 1234567 +327 1 11111111")) ->
{'+372': ['56887364', '56887364'], '+333': ['59835647'], '': ['56887364', '1234567', '11111111']}

核心问题

无法正确处理区号与号码连写的格式(如+33359835647),无法剥离区号与号码部分,同时现有实现逻辑混乱,无法对同区号号码分组。


解决方案

1. 优化正则表达式

使用捕获组分别匹配区号和号码,一次性处理带空格/无空格的带区号号码,以及无区号号码:

r'(\+\d{3})\s?(\d{7,8})|(\d{7,8})'
  • 第一组(\+\d{3}):捕获带+的3位区号;
  • \s?:匹配0或1个空格(处理区号与号码间有无空格的情况);
  • 第二组(\d{7,8}):捕获带区号的7-8位号码;
  • 第三组(\d{7,8}):捕获无区号的7-8位号码。

2. 高效实现代码

import re

def find_phone_numbers(text: str) -> dict:
    pattern = r'(\+\d{3})\s?(\d{7,8})|(\d{7,8})'
    matches = re.findall(pattern, text)
    
    phone_dict = {}
    for area_code_part, number_with_area, number_no_area in matches:
        # 确定当前号码的区号和号码内容
        area_code = area_code_part if area_code_part else ''
        current_number = number_with_area if number_with_area else number_no_area
        
        # 跳过空匹配(避免无效数据)
        if not current_number:
            continue
        
        # 维护字典:同区号号码追加到列表
        if area_code not in phone_dict:
            phone_dict[area_code] = []
        phone_dict[area_code].append(current_number)
    
    # 确保空字符串键存在(按预期输出逻辑保留)
    if '' not in phone_dict:
        phone_dict[''] = []
    return phone_dict

代码说明

  • 遍历所有正则匹配结果,通过捕获组判断号码类型(带区号/无区号);
  • 动态维护字典,自动为新增的区号创建键,并将同区号号码追加到对应列表;
  • 跳过无效匹配,避免空字符串干扰结果;
  • 兼容所有需求格式,包括连写的+33359835647(提取出区号+333,号码59835647)。

测试验证

运行示例输入,输出与预期完全一致:

{'+372': ['56887364', '56887364'], '+333': ['59835647'], '': ['56887364', '1234567', '11111111']}

内容的提问来源于stack exchange,提问作者QLimbo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:05:21