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

美国电话号码正则校验:如何拒绝区号后无右括号带空格的无效号码

解决方案

核心逻辑

原有正则的问题是没有对「区号是否带括号」和「区号后的分隔符规则」做绑定,导致无括号的区号后可以随意匹配空格。我们可以把两种合法的区号格式拆成互斥分支,分别约束后续的分隔符规则,就能精准拦截目标无效号码。

修改后完整代码

import re

def parse_us_phone(s):
    # 正则规则说明:
    # ^\s* 匹配开头可选空白字符
    # (?: 非捕获分组,包裹两种合法区号格式
    #   \((\d{3})\)\s* 第一种:带括号的区号,匹配(xxx)后可接任意空白
    #   | 或
    #   (\d{3})(?:-|(?=\d)) 第二种:不带括号的区号,后面只能接横杠或直接接数字,禁止接空格
    # )
    # [ -]* 匹配两段号码中间可选的横杠/空格
    # (\d{3}) 捕获中间3位交换码
    # [ -]* 匹配两段号码中间可选的横杠/空格
    # (\d{4}) 捕获最后4位线号
    # \s*$ 匹配结尾可选空白字符
    reg_ph = re.match(r'^\s*(?:\((\d{3})\)\s*|(\d{3})(?:-|(?=\d)))[ -]*(\d{3})[ -]*(\d{4})\s*$', s)
    if reg_ph:
        # 两个分支仅一个会捕获到区号,取非空值作为区号返回
        area_code = reg_ph.group(1) or reg_ph.group(2)
        return (area_code, reg_ph.group(3), reg_ph.group(4))
    else:
        raise ValueError('not a valid phone number')

验证效果

  • 合法号码匹配测试
print(parse_us_phone('(916) 222-1111   ')) # 输出 ('916', '222', '1111')
print(parse_us_phone('  916-2221111 ')) # 输出 ('916', '222', '1111')
print(parse_us_phone('9162221111')) # 输出 ('916', '222', '1111')
print(parse_us_phone('(916)-2221111')) # 输出 ('916', '222', '1111')
  • 无效号码拦截测试
parse_us_phone('916 111-2222') # 抛出 ValueError: not a valid phone number

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:18:01