为何re.sub(r'\n$', '', "\n\n")返回""而非"\n"?是否为预期行为?
Python re.sub匹配换行符结尾的特殊行为解析
结论
这是预期行为,根源在于Python正则表达式中$锚点的匹配规则和普通字符存在差异。
具体原因
1. 普通字符的匹配逻辑(以"aa"匹配r'a$'为例)
当执行re.sub(r'a$', '', "aa")时,$锚点仅匹配字符串的末尾位置(也就是第二个a的后面),因此只会匹配并替换最后一个a,最终返回"a",符合常规预期。
2. 换行符的特殊匹配规则(以"\n\n"匹配r'\n$'为例)
Python正则默认遵循POSIX标准,$锚点除了匹配字符串末尾,还会匹配字符串末尾换行符之前的位置。
对于字符串"\n\n"(两个连续换行符):
$会同时匹配两个位置:第二个\n的后面(字符串真正的末尾),以及第一个\n的后面(因为第二个\n是字符串的结尾换行符,$会匹配它之前的位置)。- 这就导致
r'\n$'能同时匹配两个\n:第一个\n后面跟着$匹配的位置,第二个\n后面也跟着$匹配的位置。 re.sub默认替换所有匹配项,因此两个\n都会被替换掉,最终返回空字符串""。
如何实现只替换最后一个换行符
如果想达到“去掉末尾单个换行符”的预期效果,可以使用\Z锚点替代$,\Z仅匹配字符串的绝对末尾,不受结尾换行符影响:
import re result = re.sub(r'\n\Z', '', "\n\n") print(repr(result)) # 输出 '\n'
内容的提问来源于stack exchange,提问作者Donny
相关产品推荐
相关产品推荐

