FastAPI项目中用户注册手机号即时格式化方案问询
正确实现手机号格式化的方法
先拆解你原有代码的问题:
- 正则表达式设计冗余,
match方法仅从字符串开头匹配,无法稳定捕获所有有效数字 - 存在语法错误:
"+7" ''.join(...)缺少字符串拼接的+运算符 - 未针对性处理不同输入格式的前缀差异(比如8开头、7开头、带+7的情况)
下面给出两种场景的正确实现:
场景1:处理单个手机号字符串(FastAPI接口常用)
这个函数可直接在FastAPI注册接口中调用,接收用户输入的手机号,返回格式化结果:
import re def format_phone_number(phone_input: str) -> str: # 提取输入中的所有数字字符 digits = re.sub(r"\D", "", phone_input) # 校验并处理数字长度与前缀 if len(digits) == 10: # 10位格式(如8990000000):补7前缀转为11位标准格式 full_digits = f"7{digits}" elif len(digits) == 11: if digits.startswith("8"): # 11位8开头(如89000000000):替换8为7 full_digits = f"7{digits[1:]}" elif digits.startswith("7"): # 11位7开头(如79000000000):直接使用 full_digits = digits else: raise ValueError("手机号前缀无效,仅支持7/8开头或带+7格式") else: raise ValueError("手机号必须包含10或11位数字") # 格式化为要求的tel: +7-XXX-XXX-XX-XX格式 return ( f"tel: +7-{full_digits[1:4]}-{full_digits[4:7]}-" f"{full_digits[7:9]}-{full_digits[9:]}" )
测试示例:
- 输入
"8990000000"→ 输出"tel: +7-899-000-00-00" - 输入
"79000000000"→ 输出"tel: +7-900-000-00-00" - 输入
"+79800000000"→ 输出"tel: +7-980-000-00-00"
场景2:处理DataFrame中的手机号列(对应你原有的apply用法)
如果是批量处理DataFrame的Tel列,可修改为以下实现:
import re import pandas as pd def formatting_number(df: pd.DataFrame) -> pd.DataFrame: def format_single(phone: str) -> str: digits = re.sub(r"\D", "", phone) if len(digits) == 10: full_digits = f"7{digits}" elif len(digits) == 11: if digits.startswith("8"): full_digits = f"7{digits[1:]}" elif digits.startswith("7"): full_digits = digits else: raise ValueError(f"无效手机号:{phone}") else: raise ValueError(f"无效手机号:{phone}") return f"tel: +7-{full_digits[1:4]}-{full_digits[4:7]}-{full_digits[7:9]}-{full_digits[9:]}" df["Tel"] = df["Tel"].apply(format_single) return df
关键优化点
- 用
re.sub(r"\D", "", phone)高效提取数字,替代复杂的正则捕获组 - 明确覆盖所有你提到的输入格式场景,逻辑清晰
- 增加基础校验,避免非法格式引发的错误
- 格式化字符串拆分清晰,可读性更强
内容的提问来源于stack exchange,提问作者su8a
相关产品推荐
相关产品推荐

