multiple string replace by position in python

position, python, replace, string

Solution

This is based on the idea that you should just replace going backwards through the string. First I had to modify your info and replacer structures a little bit:

str = 'If you do not know where you are going, any road will get you there.'
info = {'you': [(3, 3), (25, 3)], 'get you': [(54, 7)], 'know': [(14, 4)]}
replacer = [('you', '<b>you</b>'), ('know', '<i>know</i>')]

info2 = {}
replacer2 = {}

for original, replacement in replacer:
    replacer2[original] = replacement

for k, v in info.items():
    for start, length in v:
        replacement = None
        if k in replacer2:
            replacement = replacer2[k]
        info2[start] = (k, length, replacement)

for position in sorted(info2.iterkeys(), reverse=True):
    original, length, replacement = info2[position]
    if replacement is not None:
        str[:position] + replacement + str[position + length]

print str

Problem

I need to replace a string in a string with an augmented string. My question is, with every replace the positions of the strings in info and the original string change: How can I update it in a pythonic way? ``` str = 'If you do not know where you are going, any road will get you there.' info = {'you': [(3, 3), (25, 3)], 'get you': [(54, 7)], 'know': [(14, 4)]} # replace 'you' from info with '<b>you</b>' and 'know' with '<i>know</i>' # results in str = 'If <b>you</b> do not <i>know</i> where <b>you</b> are going, any road will get you there.' info = {'<b>you</b>': [(3, 10), (25, 10)], 'get you': [(54, 7)], '<i>know</i>': [(21, 11)]} ``` my solution so far: ``` str = 'If you do not know where you are going, any road will get you there.' info = {'you': [(3, 3), (25, 3)], 'get you': [(54, 7)], 'know': [(14, 4)]} replacer = [('you', '<b>you</b>'), ('know', '<i>know</i>')] for s, s2 in replacer: print "replacing %s to %s and update position info dict" % (s, s2) old_s_pos = info[s] diff = len(s2) - len(s) new_key_pos = [(old_s_pos[0][0], old_s_pos[0][1] + diff)] old_s_pos = old_s_pos[1:] if old_s_pos: next_old_s_pos_start = old_s_pos[0][0] else: next_old_s_pos_start = None del info[s] for key, positions in info.iteritems(): new_positions = [] for i, (x,y) in enumerate(positions): if x < next_old_key_pos_start: new_positions.append((x + diff, y)) else: new_positions.append((x, y)) if next_old_s_pos_start is not None: # update old_s_pos at first pair new_key_pos.append((old_key_pos[0][0], old_s_pos[0][1] + diff)) old_s_pos = old_s_pos[1:] if old_s_pos: next_old_s_pos_start = old_s_pos[0][0] info[key] = new_positions info[s2] = new_key_pos print info ``` Kind regards, Matthias

Original source