2016-01-29 181 views
4

我想替換字符串中第n個出現的子字符串。替換字符串中出現的第n個子字符串

一定有什麼東西相當於什麼我想要做的是

mystring.replace("substring", 2nd)

什麼是實現這一目標的最簡單,最Python的方式?

爲什麼不重複:我不想使用這種方法的正則表達式,我發現大多數類似問題的答案只是正則表達式的剝離或真正複雜的功能。我真的希望儘可能簡單,而不是正則表達式解決方案。

+1

@Tiger哇。你如何找到確切的愚蠢?似乎我的答案也在那裏.. :-) –

+0

回覆:不重複:請讀過去的第一個答案。 – TigerhawkT3

+0

@ TigerhawkT3啊,我明白了。他要求提供正則表達式解決方案,但他也得到了非正則表達式的答案。我沒有讀過它們。你能編輯他的問題嗎? – aleskva

回答

0

我使用簡單的函數,它列出所有的事件,選擇第n個位置並使用它將原始字符串拆分爲兩個子字符串。然後,它取代了第二子第一次出現,並加入子回新的字符串:

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 

對於這些變量:

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

輸出:

ababababCDabababab 

注:

The where變量實際上是一系列匹配的位置,你從哪裏拿到第n個。但是列表項索引通常以0開頭,而不是1。因此有一個n-1索引和n變量是實際的第n個子字符串。我的例子發現第五個字符串如果您使用n索引並想查找第5個位置,則需要n4。你使用的通常取決於功能,它產生我們的n

這應該是最簡單的方法,但也許它不是最Pythonic方式,因爲where變量構造需要導入re庫。也許有人會發現更多的Pythonic方式。

來源,另外一些鏈接:

5

您可以使用while循環使用str.find找到第n個出現,如果它ex派並使用該位置來創建新的字符串:

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' 
1

最後的答案几乎是完美的 - 只有一個修正:

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 

後串有在更換後再次存儲在這個變量中。 謝謝你的偉大的解決方案!

1

我已經想出了下面的內容,它也考慮了將所有「舊」字符串事件替換爲左側或右側的選項。自然,沒有選擇來替換所有的事件,因爲標準的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) 
相關問題