re.sub和re.findall的区别
我有一些字符串,比如“Billboard Bill SpA”。我想要一个正则表达式,能够去掉“SpA”,但前提是它前面有一个大写字母开头的单词。我现在用的正则表达式是“[A-Z][a-z]*\s(SpA)”。但是如果我用re.sub,这样会把“SpA”和它前面的那个大写单词都去掉,这个结果是我不想要的。
re.sub("[A-Z][a-z]*\s(SpA)", "", "Billboard Bill SpA")
'Billboard '
不过,如果我用re.findall,就能得到我想要的效果:
re.findall("[A-Z][a-z]*\s(SpA)", "Billboard Bill SpA")
['SpA']
我知道我可以用一个前瞻表达式“?<=”来处理,这样就不会消耗掉前面的文本,但这个方法只适用于固定长度的表达式。有没有人知道我该怎么做,才能只用re.sub去掉“SpA”,或者让它像re.findall那样工作呢?
更清楚一点说,我想要一个正则表达式,只去掉“SpA”,前提是它前面有一个大写字母开头的单词:
re.sub(regular_expresssion, "", "Billboard Bill SpA") -> Billboard Bill
re.sub(regular_expresssion, "", "to SpA") -> to SpA
2 个回答
1
使用分组来进行替换。
>>> re.sub("([A-Z][a-z]*\s)(SpA)", "\\1", "Billboard Bill SpA")
'Billboard Bill '
2
你的 re.sub
是在替换整个匹配的内容,而不仅仅是 (SpA)
这一部分。这就是为什么它也把 Bill
给去掉了。另一方面,findall
则是只给你想要的那部分。
在 re.sub
中,你可以指定保留你不想删除的匹配部分。
re.sub("([A-Z][a-z]*\s)SpA", "\\1", "Billboard Bill SpA")
'Billboard Bill '
如果你想把空格也去掉,可以把 \s
移到括号外面。