replacestring中出现的第n个子string

我想要replacestring中第n个子string的出现。

有什么相当于我想要做的是什么

mystring.replace("substring", 2nd)

什么是最简单,最Pythonic的方式来实现这一目标?

为什么不重复:我不想使用这种方法的正则expression式,我发现大多数类似问题的答案只是正则expression式剥离或真正复杂的function。 我真的想要尽可能简单,而不是正则expression式的解决scheme。

您可以使用str.find的while循环来查找第n个匹配项(如果存在),并使用该位置创build新的string:

 def nth_repl(s, sub, repl, nth): find = s.find(sub) # if find is not p1 we have found at least one match for the substring i = find != -1 # loop util we find the nth or we find no match while find != -1 and i != nth: # find + 1 means we start at the last match start index + 1 find = s.find(sub, find + 1) i += 1 # if i is equal to nth we found nth matches so replace if i == nth: return s[:find]+repl+s[find + len(sub):] return s 

例:

 In [14]: s = "foobarfoofoobarbar" In [15]: nth_repl(s, "bar","replaced",3) Out[15]: 'foobarfoofoobarreplaced' In [16]: nth_repl(s, "foo","replaced",3) Out[16]: 'foobarfooreplacedbarbar' In [17]: nth_repl(s, "foo","replaced",5) Out[17]: 'foobarfoofoobarbar' 

最后的答案几乎是完美的 – 只有一个更正:

  def replacenth(string, sub, wanted, n): where = [m.start() for m in re.finditer(sub, string)][n - 1] before = string[:where] after = string[where:] after = after.replace(sub, wanted) newString = before + after return newString 

更换后,必须将后string再次存储在此variables中。 感谢您的伟大的解决scheme!

我已经提出了下面这个,它也考虑了将所有“旧”string发生replace为左侧或右侧的选项。 自然,没有select来replace所有的事件,因为标准的str.replace工作完美。

 def nth_replace(string, old, new, n=1, option='only nth'): """ This function replaces occurrences of string 'old' with string 'new'. There are three types of replacement of string 'old': 1) 'only nth' replaces only nth occurrence (default). 2) 'all left' replaces nth occurrence and all occurrences to the left. 3) 'all right' replaces nth occurrence and all occurrences to the right. """ if option == 'only nth': left_join = old right_join = old elif option == 'all left': left_join = new right_join = old elif option == 'all right': left_join = old right_join = new else: print("Invalid option. Please choose from: 'only nth' (default), 'all left' or 'all right'") return None groups = string.split(old) nth_split = [left_join.join(groups[:n]), right_join.join(groups[n:])] return new.join(nth_split) 

我使用简单的函数,它列出所有的事件,select第n个位置,并使用它将原始string拆分成两个子string。 然后,它将replace第二个子string中的第一个匹配项,并将子string连接回新的string:

 import re def replacenth(string, sub, wanted, n) where = [m.start() for m in re.finditer(sub, string)][n-1] before = string[:where] after = string[where:] after = after.replace(sub, wanted, 1) newString = before + after print newString 

对于这些variables:

 string = 'ababababababababab' sub = 'ab' wanted = 'CD' n = 5 

输出:

 ababababCDabababab 

笔记:

wherevariables实际上是匹配位置的列表,在那里你select第n个位置。 但是,列表项索引通常以0开头,而不是1 。 因此有一个n-1索引, nvariables是实际的第n个子string。 我的例子发现第五个string 如果您使用n索引并且想要find第5个位置,则需要n4 。 你使用的通常取决于函数,它产生了我们的n

这应该是最简单的方法,但也许它不是最Pythonic的方式,因为wherevariables的build设需要导入库。 也许有人会发现更多的Pythonic方式。

来源和一些链接另外:

  • where构造: 在Python中查找所有出现的子string
  • string拆分: https : //www.daniweb.com/programming/software-development/threads/452362/replace-nth-occurrence-of-any-sub-string-in-a-string
  • 类似的问题: findstring中第n个子string的出现