Replace nth occurrence of substring in string

后端 未结 10 2345
面向向阳花
面向向阳花 2020-11-27 06:51

I want to replace the n\'th occurrence of a substring in a string.

There\'s got to be something equivalent to what I WANT to do which is

mystring.repl

相关标签:
10条回答
  • 2020-11-27 07:33

    I've tweaked @aleskva's answer to better work with regex and wildcards:

    import re
    
    def replacenth(string, sub, wanted, n):
        pattern = re.compile(sub)
        where = [m for m in pattern.finditer(string)][n-1]
        before = string[:where.start()]
        after = string[where.end():]
        newString = before + wanted + after
    
        return newString
    
    replacenth('abdsahd124njhdasjk124ndjaksnd124ndjkas', '1.*?n', '15', 1)
    

    This gives abdsahd15jhdasjk124ndjaksnd124ndjkas. Note the use of ? to make the query non-greedy.

    I realise that the question explicitly states that they didn't want to use regex, however it may be useful to be able to use wildcards in a clear fashion (hence my answer).

    0 讨论(0)
  • 2020-11-27 07:34

    You can use a while loop with str.find to find the nth occurrence if it exists and use that position to create the new string:

    def nth_repl(s, sub, repl, n):
        find = s.find(sub)
        # If find is not -1 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 != n:
            # find + 1 means we start searching from after the last match
            find = s.find(sub, find + 1)
            i += 1
        # If i is equal to n we found nth match so replace
        if i == n:
            return s[:find] + repl + s[find+len(sub):]
        return s
    

    Example:

    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'
    
    0 讨论(0)
  • 2020-11-27 07:36

    My two cents

    a='01ab12ab23ab34ab45ab56ab67ab78ab89ab90';print('The original string: ', a)
    sTar = 'ab';print('Look for: ', sTar)
    n = 4; print('At occurence #:', n)
    sSub = '***';print('Substitute with: ', sSub)
    
    t = 0
    for i in range(n):
       t = a.find(sTar,t)
       print(i+1, 'x occurence at', t)
       if t != -1: t+=1
    
    t-=1   #reset, get the correct location
    yy = a[:t] + a[t:].replace(sTar, sSub, 1)
    print('New string is:', yy)
    

    Output

    The original string:  01ab12ab23ab34ab45ab56ab67ab78ab89ab90
    Look for:  ab
    At occurence #: 4
    Substitute with:  ***
    1 x occurence at 2
    2 x occurence at 6
    3 x occurence at 10
    4 x occurence at 14
    New string is: 01ab12ab23ab34***45ab56ab67ab78ab89ab90
    
    0 讨论(0)
  • 2020-11-27 07:43

    I had a similar need, i.e to find the IPs in logs and replace only src IP or dst IP field selectively. This is how i achieved in a pythonic way;

    import re
    
    mystr = '203.23.48.0 DENIED 302 449 800 1.1 302 http d.flashresultats.fr  10.111.103.202 GET GET - 188.92.40.78 '
    src = '1.1.1.1'
    replace_nth = lambda mystr, pattern, sub, n: re.sub(re.findall(pattern, mystr)[n - 1], sub, mystr)
    result = replace_nth(mystr, '\S*\d+\.\d+\.\d+\.\d+\S*', src, 2)
    print(result)
    
    0 讨论(0)
提交回复
热议问题