我正在尝试编写一个函数,该函数返回一个字符串,其中第 n 个子字符串被新的子字符串替换。
我尝试了以下方法:
import re
from itertools import count
text = "Hello_Dear_Today_is_Nice_Today_is_Nice"
def replace_nth(text, sub, rep_sub, n):
c = count(0)
res = re.sub(r"{}".format(sub), lambda x: rep_sub if next(c) == n else x.group(), text)
return res
print(replace_nth(text, "Today", "Today_2", 2))
但是返回的字符串是一样的,我做错了什么?
我期待:
结果Hello_Dear_Today_is_Nice_Today_2_is_Nice
尝试:
import re
from itertools import islice
def replace_nth(text, sub, rep_sub, n):
r = re.finditer(re.escape(sub), text)
for m in islice(r, n - 1, n):
text = f"{text[:m.start()]}{rep_sub}{text[m.end():]}"
break
return text
text = "Hello_Dear_Today_is_Nice_Today_is_Nice"
print(replace_nth(text, "Today", "Today_2", 2))
打印:
Hello_Dear_Today_is_Nice_Today_2_is_Nice
我猜你想从后面更换它。
如果是这样的话,您可以简单地使用
split()
:
text = "Hello_Dear_Today_is_Nice_Today_is_Nice"
def replace_nth(text, sub, rep_sub, n):
s = text.split('_')
s[-n - 1] = rep_sub
return '_'.join(s)
print(replace_nth(text, "Today", "Today_2", 2))
Hello_Dear_Today_is_Nice_Today_2_is_Nice
编辑:
您似乎正在尝试从左侧进行匹配。在这种情况下:
def replace_nth(text, sub, rep_sub, n):
s = text.split('_')
for i, word in enumerate(s):
if word.startswith(sub):
n -= 1
if n == 0:
s[i] = rep_sub
break
return '_'.join(s) if n == 0 else 'False inputs'
text = "Hello_Dear_Today_is_Nice_Today_is_Nice"
print(replace_nth(text, "Today", "Today_2", 2))
print(replace_nth(text, "Today", "Today_2", 4))
print(replace_nth(text, "Today", "Today_2", 1))
Hello_Dear_Today_is_Nice_Today_2_is_Nice
False inputs
Hello_Dear_Today_2_is_Nice_Today_is_Nice
一种方法是使用 re.finditer():
from re import finditer
text = "Hello_Dear_Today_is_Nice_Today_is_Nice"
def replace_nth(text, sub, rep_sub, n):
m = list(finditer(sub, text))
try:
return f"{text[0:m[n].span()[0]]}{rep_sub}{text[m[n].span()[1]:]}"
except IndexError:
return text
x = replace_nth(text, "Today", "Today_2", 1)
print(x)
通过异常处理完成的小错误处理将确保如果未找到第
n
匹配项或 text
不包含 sub
,则返回原始文本。
没有任何依赖,肯定比 re/itertools 快很多。 如果字符串包含子字符串 n 次,则分割后的数字必须为 n+1 。如果情况并非如此,该函数将返回 None
def replace_nth(text, sub, rep_sub, n):
return (sub.join(g[:n]) + rep_sub + g[n]) if len(g:=text.split(sub,maxsplit=n))==n+1 else None
text = "Hello_Dear_Today_is_Nice_Today_is_Nice"
print(replace_nth(text, "Today", "Today_2", 2))
您可以在匹配第 n 次出现的
n - 1
之前构建一个匹配 sub
出现的 sub
的正则表达式:
def replace_nth(text, sub, rep_sub, n):
if n > 1:
sub = rf'^(.*?(?:{sub}.*?){{{n - 1}}}){sub}'
rep_sub = r'\1' + rep_sub
return re.sub(sub, rep_sub, text, count=1)