在文本中替换除最后一次出现的字符串

7

假设我有这段文字:

Saturday and Sunday and Monday and Tuesday and Wednesday and Thursday and Friday are days of the week.  

我希望除了最后一个 and 以外,其他的都用逗号替换:
Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday and Friday are days of the week. 

有没有一种简单的正则表达式方法可以实现这个?据我所知,正则表达式中的replace方法会替换整个字符串。


5
我看到你没有使用牛津逗号。 - Peter Wood
严格来说,正则表达式只进行匹配,而替换是托管语言的特性,通常是其字符串处理功能。 - tripleee
这里的代码写得有点难以理解。或许你可以拿它取乐。"".join(reduce(lambda x , y : x+["and"+y] if len(x)==0 else x+[","+y] ,re.split("and","Saturday and Sunday and Monday and Tuesday and Wednesday and Thursday and Friday are days of the week. ")[::-1],[])[::-1])[1:] - Akshay Hazari
2个回答

18

str.replace() 方法有一个 count 参数:

str.replace(old, new[, count])

返回字符串的副本,将所有旧子字符串替换为新字符串。如果给定了可选参数 count,则只替换前 count 次出现。

然后,使用 str.count() 检查字符串中有多少个 and,然后减去 -1(因为你需要最后一个 and):

str.count(sub[, start[, end]])

返回子字符串 sub 在范围 [start, end] 中的非重叠出现次数。可选参数 start 和 end 的解释方式与切片相同。

演示:

>>> string = 'Saturday and Sunday and Monday and Tuesday and Wednesday and Thursday and Friday are days of the week.'   
>>> string.replace(' and ', ", ", (string.count(' and ')-1))
'Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday and Friday are days of the week.  '

4
如果你想使用正则表达式解决问题,可以匹配字符串中后面跟着另一个 and 的所有 and
>>> str='Monday and Tuesday and Wednesday and Thursday and Friday and Saturday and Sunday are the days of the week.'
>>> import re
>>> re.sub(' and (?=.* and )', ', ', str)
'Monday, Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday are the days of the week.'

(?=...)是一个前瞻,它确保字符串中后面有匹配项,而不包括在实际匹配中(因此也不包括在替换中)。它有点像对匹配的条件限制。


这个字符串会发生什么事情:'星期一、星期二、星期三、星期四、星期五、星期六和星期日是一周的日子,今天是星期一。' - kylieCatt
那很容易找出来,不是吗?也许可以将前瞻中的.*更改为[^.?!]*,以避免它匹配到句子标点符号。但是如何处理带有点号的句间缩写,而该点号不是句子终止符?您很快就会遇到Zawinski's problem(两难问题)。对于除简单标记外的任何内容,正则表达式可能不是合适的工具。 - tripleee
但是对于这个简单的问题,您可能甚至可以将其限制得更严格,并希望它永远不会匹配超过动词。 "约翰、玛丽和我去了白金汉宫并喝了一杯啤酒。" - tripleee
作为一种解决方法(在某些情况下也可能失败),您可以限制每个“and”之间的单词数,即:' and (?=(?:[^.,?! ]+ ){1,4}and )' - Mariano
@ Mariano John 和 John 的表弟的丈夫的狗还有我...?实际上,这是一个针对有限范围的不错想法,但你不能用正则表达式解决一般性问题。 - tripleee
@tripleee 确实,你不能用正则表达式解决一般情况。我只是提出了另一种选择,但在某些情况下也会失败。 - Mariano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接