Python 正则清理空格分隔单数字并保留多位数日期的方案
Python 正则实现方案
直接通过零宽断言锁定符合规则的数字片段,配合re.sub一次替换即可完成处理,无需多轮遍历或复杂逻辑。
import re def merge_single_digits(text: str) -> str: # 匹配被非数字/字符串边界包裹的、空格分隔的连续单个数字序列 pattern = r'(?<!\d)(\d(?: \d)+)(?!\d)' # 替换时仅删除匹配片段内的所有空格 return re.sub(pattern, lambda match: match.group().replace(' ', ''), text)
效果验证
# 原问题给出的样例 text1 = "0 1 loren ipsum 1 2 3 dolor sit 4 5 6 amet -7 8 9 1- date 13 06 2022" print(merge_single_digits(text1)) # 输出:01 loren ipsum 123 dolor sit 456 amet -7891- date 13 06 2022,完全匹配预期结果 # 日期边界测试样例 text2 = "1 1 1970" print(merge_single_digits(text2)) # 输出:11 1970,符合规则要求 # 其他边界场景测试 text3 = "a 2 3 4 b 56 7 8 c 90" print(merge_single_digits(text3)) # 输出:a 234 b 56 78 c 90,多数字组成的号段不受影响
正则逻辑说明
(?<!\d):负向后行断言,只做位置校验、不占用匹配内容,保证匹配片段的起始位置前没有其他数字,避免误匹配多位数的后半段,同时天然支持字符串开头的数字序列匹配\d(?: \d)+:核心匹配规则,匹配1个单个数字后接1组或多组「空格+单个数字」的结构,刚好对应需要合并的连续单数字片段(?!\d):负向前瞻断言,保证匹配片段的结束位置后没有其他数字,避免误匹配多位数的前半段,同时支持字符串结尾的数字序列匹配
之前使用的正则问题在于前置的(.*?\D)捕获组把非数字前缀纳入了匹配范围,不仅无法匹配字符串开头的数字,替换时还要额外处理捕获组内容的保留,逻辑冗余,用零宽断言做边界校验就能直接绕开这个问题。
如果追求极致性能不想用lambda回调,也可以写纯替换式正则,但可读性会明显下降,对于OCR文本处理场景,当前写法的可维护性和性能完全够用。
内容的提问来源于stack exchange,提问作者tinkerbeast
相关产品推荐
相关产品推荐

