匹配英文缩写字的正则表达式失效,求排查解决
问题分析与解决
首先,你的正则表达式失效的核心原因是**re.findall的行为特性**:当正则表达式中包含捕获组(即带括号的部分)时,findall会优先返回捕获组的匹配结果,而不是整个正则匹配的完整内容。
看你的正则\w+(\'\w+)?|[!-~]:
- 第一个分支
\w+(\'\w+)?里有一个捕获组(\'\w+),用来匹配缩写里的撇号和后续字符(比如can't里的't)。当匹配普通单词(比如This)时,这个捕获组没有匹配到任何内容,所以findall会返回空字符串; - 第二个分支
[!-~]虽然没有捕获组,但因为整个正则存在捕获组,findall依然会遵循“优先返回捕获组”的逻辑——当匹配到标点时,捕获组没有内容,所以也返回空字符串; - 只有当匹配到
can't这类缩写时,捕获组会匹配到't,这时候findall才会返回't,而不是完整的can't。
修复方案
把捕获组改成非捕获组(用(?:...)代替(...)),这样findall就会返回整个正则匹配的完整内容,而不是捕获组的结果:
import re result = re.findall(r"\w+(?:\'\w+)?|[!-~]", "This is a test. Lulz another sentence. This can't be real.") print(result)
运行这段代码,你会得到预期的结果:
['This', 'is', 'a', 'test', '.', 'Lulz', 'another', 'sentence', '.', 'This', "can't", 'be', 'real', '.']
额外优化建议
你的[!-~]匹配的是所有ASCII可打印非空格字符,虽然能覆盖标点,但可能会匹配到一些你不需要的字符(比如@、#等)。如果只需要匹配常见的句子标点,可以把这个分支改成更精准的范围,比如:
re.findall(r"\w+(?:\'\w+)?|[.,!?;:'\"]", 你的文本)
内容的提问来源于stack exchange,提问作者Dwagner
相关产品推荐
相关产品推荐

