Python正则如何匹配首个完整地址后停止并返回正确结果
Python正则匹配首个有效地址方案
问题根因
原正则末尾添加了$锚点,强制要求匹配到字符串结束位置,哪怕开启非贪婪模式,正则引擎也会为了满足整串匹配的规则持续向后扫描、回溯,无法在第一个门牌号位置终止。直接在表达式末尾加(.*?)失效也是同样的原因——锚点规则优先级高于非贪婪的最短匹配逻辑。
修正后正则
import re addr_re = re.compile( r'^([A-Za-zÄäÖöÜüß\s\d.-]+?)\s*(\d+\s*(?:[-+/]\s*\d+)?\s*[A-Za-z]?(?:-[A-Za-z])?)' )
匹配逻辑说明
- 移除了原正则末尾的
$锚点,正则扫描到符合「街道名称+标准门牌号」规则的片段后会自动终止匹配,不会继续读取后续的附加内容 - 调整门牌号匹配规则:强制门牌号以数字开头,避免将街道名称中的字符、后缀符号误判为门牌号组成部分
- 原生支持所有标准门牌号格式:连字符/斜杠/加号连接的多门牌号、门牌号后缀大小写字母、字母后缀范围
测试效果
所有样本的匹配结果完全符合预期:
- 输入
Berliner Str. 74→ 输出Berliner Str. 74 - 输入
Hindenburgdamm 27, Hygiene-Institut→ 输出Hindenburgdamm 27(遇逗号自动截断,不匹配后续机构名) - 输入
Peschkestr. 5a/Holsteinische Str. 44→ 输出Peschkestr. 5a(遇斜杠自动截断,不匹配后续第二个地址) - 输入
Lankwitzer Str. 13-17a→ 输出Lankwitzer Str. 13-17a - 输入
Fidicinstr. 15A→ 输出Fidicinstr. 15A - 输入
Haudegen Weg 15/17→ 输出Haudegen Weg 15/17 - 输入
Johanna-Stegen-Strasse 14a-d→ 输出Johanna-Stegen-Strasse 14a-d - 输入
Friedrichshaller Str. 7→ 输出Friedrichshaller Str. 7 - 输入
Südwestkorso 9→ 输出Südwestkorso 9
调用示例
直接使用match()方法从字符串起始位置匹配即可,取匹配结果的完整分组值:
test_list = [ "Berliner Str. 74", "Hindenburgdamm 27, Hygiene-Institut", "Peschkestr. 5a/Holsteinische Str. 44", "Lankwitzer Str. 13-17a", "Fidicinstr. 15A", "Haudegen Weg 15/17", "Johanna-Stegen-Strasse 14a-d", "Friedrichshaller Str. 7", "Südwestkorso 9" ] for item in test_list: match_res = addr_re.match(item) if match_res: print(match_res.group(0))
注意:非贪婪模式的「最短匹配」特性,仅在没有更高优先级锚点规则约束时生效。如果正则中存在$这类要求匹配到串尾的锚点,引擎会优先满足锚点规则,非贪婪模式不会按预期截断结果。
内容的提问来源于stack exchange,提问作者oddbook
相关产品推荐
相关产品推荐

