str.replace() 或 re.sub() 持续直到子字符串不再存在

str.replace() or re.sub() continually until substring no longer present

假设我有以下字符串:'streets are shiny.' 我希望找到字符串 'st' 的每个匹配项并将其替换为 'ts'。所以结果应该是 'tseets are shiny'.

我知道这可以使用 re.sub()str.replace() 来完成。但是,假设我有以下字符串:

  1. 'st'
  2. 'sts'
  3. 'stst'

我希望它们分别更改为 'ts''tss''ttss',因为我希望所有出现的 'st' 都更改为 'ts'

用最佳运行时间替换这些字符串的最佳方法是什么?我知道我可以不断地执行检查以查看 if "st" in string 直到 returns False,但是有更好的方法吗?

我认为在这种情况下,只检查 'st' 是否在字符串中的 while 循环是最好的:

def recursive_replace(s, sub, new):
    while sub in s:
        s = s.replace(sub, new)
    return s

tests = ['st', 'sts', 'stst']
print [recursive_replace(test, 'st', 'ts') for test in tests]
#OUT:  ['ts', 'tss', 'ttss']

您可以使用一个非常简单的 while 循环来做到这一点:

s="stst"
while('st' in s):
  s = s.replace("st", "ts")
print(s)

ttss

如果你想不断地检查,那么其他问题就很有效(问题是如果你有类似 stt 你会得到 stt->tst-> tts)。不知道要不要。

不过,我认为您正试图用 ts 替换多次出现的 st。如果是这样,您绝对应该使用 string.replace。 .replace 替换每次出现的 str,直到你想要的程度。

根据 this,这应该更快。

string.replace(s, old, new[, maxreplace])

示例:

>>>import string
>>>st='streets are shiny.streets are shiny.streets are shiny.'
>>>string.replace(st,'st','ts')
#out: 'tsreets are shiny.tsreets are shiny.tsreets are shiny.'

虽然循环解决方案可能是最简单的,但您实际上可以使用自定义函数编写 re.sub 调用来一次完成所有转换。

对此的关键见解是您的规则(将 st 更改为 ts)最终将移动混合块中的所有 ss ss ts 在所有 ts 的右边。我们可以简单地数出st,并进行适当的替换:

def sub_func(match):
    text = match.group(1)
    return "t"*text.count("t") + "s"*text.count("s")

re.sub(r'(s[st]*t)', sub_func, text)

你可以天真地做:

>>> ['t'*s.count('t')+'s'*s.count('s') for s in ['st', 'sts', 'stst']]
['ts', 'tss', 'ttss']