Python正则匹配标点后空格并排除特定缩写的技术问询
解决正则分割句子时的缩写/头衔/地名边缘问题
这问题我太懂了——用re.split分割长文本时,最烦的就是那些带点的缩写、头衔和地名,一不小心就把完整的内容拆得七零八落。给你一个精准的正则方案,完美适配你给出的示例场景:
最终正则与代码示例
import re # 你的示例文本 text = "I am from New York, N.Y. and I would like to say hello! How are you today? I am well. I owe you $6. 00 because you bought me a No. 3 burger. -Sgt. Smith" # 核心正则表达式 split_pattern = r'(?<=[.!?])(?<!\b[A-Z]\.)(?<!\bNo\.)(?<!\bSgt\.)(?<!\b\d\.)\s+' # 执行分割 result = re.split(split_pattern, text) print(result)
运行后输出完全符合你的预期:
["I am from New York, N.Y. and I would like to say hello!", "How are you today?", "I am well.", "I owe you $6. 00 because you bought me a No. 3 burger.", "-Sgt. Smith"]
正则逻辑拆解
这个正则用负向后行断言精准排除了所有不需要分割的边缘情况,逐个部分解释:
(?<=[.!?]):基础条件——确保分割位置前面是句子结束的标点(./?/!)(?<!\b[A-Z]\.):排除单个大写字母加.的情况(比如N.Y.里的N.和Y.)(?<!\bNo\.):专门排除No.这种序号缩写(?<!\bSgt\.):排除Sgt.这类头衔缩写(?<!\b\d\.):排除数字加.的情况(比如$6. 00里的6.)\s+:匹配标点后面的空格,作为实际的分割触发点
扩展性说明
如果之后遇到其他需要排除的缩写(比如Mr./Mrs./Dr.),只需要在正则里追加对应的负向后行断言即可,比如:
# 新增排除Mr.和Dr.的版本 extended_pattern = r'(?<=[.!?])(?<!\b[A-Z]\.)(?<!\bNo\.)(?<!\bSgt\.)(?<!\bMr\.)(?<!\bDr\.)(?<!\b\d\.)\s+'
内容的提问来源于stack exchange,提问作者wfgeo




