别用单一大而全的正则匹配整个地址,应分层剥离干扰项:先清除固定格式电话、邮箱及纯乱码,保留中文、字母、数字和常见标点,再针对性提取门牌号并校验上下文。

地址里混着电话、邮箱、乱码,re.sub() 怎么写才不误删?
直接上结论:别用单一大而全的正则去“匹配整个地址”,先分层剥离干扰项。地址混乱时,最常误删的是带数字的街道名(如“长安街1号”被当成电话删掉)或含@的小区名(如“梧桐@社区”被当成邮箱干掉)。
实操建议:
- 优先用
re.sub()清除明确无歧义的噪声:固定格式电话(r'\d{3,4}-?\d{7,8}')、邮箱(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')、纯乱码段(r'[^\w\u4e00-\u9fa5\s,。!?;:""''()【】《》、\-]+',注意保留中文、字母、数字、常见标点) - 避免一步到位:比如用
r'.*?(\d{1,4}[\u4e00-\u9fa5]+).*'提取门牌号,容易把“3号楼东侧”错判成“3号”,应拆成“先找‘号’‘栋’‘楼’前的连续数字”再校验上下文 - 电话清洗要加边界锚定:
r'(?,否则“13812345678abc”会只删掉中间8位,留个“138”在地址里
中文地址中“省市区”层级错乱,re.findall() 怎么稳定提取?
“北京市朝阳区建国路8号华润大厦”能分,“朝阳区建国路8号北京市华润大厦”就容易把“朝阳区”当市、“北京市”当省,导致层级倒挂。根本原因是中文地址没强制语法,正则不能靠顺序猜层级。
实操建议:
- 用预定义关键词集合做锚点,而非单纯靠字数或位置:构建省级关键词列表(
['北京市', '上海市', '广东省', '新疆维吾尔自治区']),再用re.findall(r'(' + '|'.join(province_list) + r')', text)定位省 - 区/县级必须紧邻市级之后出现才可信:匹配“[市][\u4e00-\u9fa5]{2,5}[区|县]”,但得前置检查前面是否已捕获市级(如“深圳市南山区”,不能单独匹配“南山区”就认定为区)
- 对“XX区XX路”这类高频结构,用
re.search(r'([\u4e00-\u9fa5]{2,8}?(?:区|市|县))([\u4e00-\u9fa5]{2,10}?(?:路|街|大道|巷|弄))', text)比泛泛匹配更稳
门牌号带括号、斜杠、字母,re.compile() 需要怎么编译才抗干扰?
“浦东新区张江路123(乙)号”“天河区体育西路103/105号”“杭州市西湖区文三路321-A座”——这些不是异常,是真实数据。用 r'\d+[^a-zA-Z\d\s]*[a-zA-Z]?' 会把“123(乙)”吃成“123(乙”,漏掉右括号。
实操建议:
- 把门牌号定义为“数字开头,后接零到多个非空白、非句号、非逗号的字符,且以汉字‘号’‘座’‘单元’或空格/标点结尾”:模式写成
r'\d+[^\s。、,]*?(?=[\s。、,号座单元]|$)' - 提前用
re.compile()编译并启用re.IGNORECASE和re.UNICODE,尤其处理“NO.123”“no.45”时大小写不敏感很关键 - 对“103/105”这种复合号,先用
r'\d+(?:/\d+)*'提取完整片段,再按需拆分,别强行塞进单个门牌字段
清洗后地址仍含残留符号或空格,str.strip() 和 re.sub() 哪个该用?
str.strip() 只清首尾,对“朝阳区 建国路 8号”里的中文全角空格、不间断空格(\xa0)、制表符完全无效;而盲目用 re.sub(r'\s+', ' ', s) 会把“中关村大街二段”里的“二段”缩成“二段”(看起来一样,但中间多空格其实改变了语义分词)。
实操建议:
- 统一清理空白符:用
re.sub(r'[\s\u3000\xa0]+', ' ', s).strip(),其中\u3000是中文全角空格,\xa0是不间断空格 - 保留必要连接符:清洗后若出现“北京市 朝阳区”,中间两个空格可压成一个;但“丰台区 南苑路”里的空格是层级分隔,不该动结构——所以最终用
.replace(' ', ' ').strip()更可控 - 特别注意顿号、逗号:地址中“徐汇区、长宁区”是两个地址,不是单个地址里的标点,清洗前得先判断分隔符是否在同一条记录内
真正难的不是写对某条正则,而是判断哪部分该信规则、哪部分该信词典、哪部分必须人工映射。比如“陆家嘴环路”和“陆家嘴环路100号”,前者是道路名,后者是地址,但正则眼里都是“文字+数字+号”。这时候就得切出去查标准地名库,或者加业务规则兜底。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











