Substituting found regex based on rank

Question:

In python how could we replace all matched cases of a pattern say '(AB)(.*?)(CD)' in text based on rank? for example reach from

bla bla blab ABftrCD bla bla ABgtCD bla blab ABnyhCD

to

bla bla blab ABftrCDn1 bla bla ABgtCDnn2 bla blab ABnyhCDnnn3
Asked By: moshtaba

||

Answers:

Using function in re.sub for replacement with a variable to keep track of replacement occurrence number

  • used function attribute for variable but using a global variable is another option.

Code

import re

def func_replace(m):
    '''
        Replacement function used with re.sub
    '''
    func_replace.cnt += 1    # increment occurence count
    
    return f"{m.group(0)}n{func_replace.cnt}"

s = "bla bla blab ABftrCD bla bla ABgtCD bla blab ABnyhCD"

func_replace.cnt = 0   # initialize function cnt attribute (each time before calling re.sub)
print(re.sub(r'(AB)(.*?)(CD)', func_replace, s))

# Output: 'bla bla blab ABftrCDn1 bla bla ABgtCDn2 bla blab ABnyhCDn3'
Answered By: DarrylG

Also you can use traditional loop for it:

def regex_number(string):
    
    finding = True
    l = 0
    k = 0
    while finding:

        i = string[l:].find('AB')

        if (i >= 0):

            j = string[l+i+2:].find('CD')

            if (j >= 0):

                k += 1
                sk = str(k)
                string = string[:l+i+j+4] + 'n'*k + sk + string[l+i+j+4:]
                l += i + j + k + len(sk) + 4

            if (j == -1):
                finding = False

        if (i == -1):
            finding = False

    return string
Answered By: Ali Ashja'
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.