Reputation: 190709
I need to replace a set of pattern matched strings to another one. For example, given a list [10, 20, 30, 40, 50] and a string "a b c d e", I need to replace five letters to each element in the list keeping the order: "10 20 30 40 50". The real case is much more complicated, so I need to use regular expression to find patterns.
I could implement the code as follows, but the issues is that the duplicated letter 'a' is replaced with the same value 10 when the 2nd 'a' should be replaced with '30'.
l = [10, 20, 30, 40, 50]
inp = "a 1 b 2 a 3 d 4 e"
pattern = re.compile("([^\d]+)+(\s+)?")
items = pattern.findall(inp)
print items
for i, item in enumerate(items):
value = str(l[i])
inp = re.sub(item[0].strip(), value, inp)
print inp
# 10 1 20 2 10 3 40 4 50 <-- Wrong result. The 10 is replaced with first and third match.
# It should have been 10 1 20 2 30 3 40 4 50
How can I solve this issue?
Upvotes: 1
Views: 102
Reputation: 190709
The re.sub has an optional count to limit the maximum match. With the setup of count as 1, everything seems to be working fine.
import re
l = [10, 20, 30, 40, 50]
inp = "a 1 b 2 a 3 d 4 e"
pattern = re.compile("([a-zA-Z]+)")
items = pattern.findall(inp)
print items
for i, item in enumerate(items):
value = str(l[i])
inp = re.sub(item[0], value, inp, 1)
print inp
# 10 1 20 2 30 3 40 4 50
Or
repl = iter(l)
# You can use function or lambda
# def rep_obj(matchobj): print matchobj.group(0); return str(next(repl))
result = re.sub("([a-zA-Z]+)", lambda m: str(next(repl)), inp)
print result
# 10 1 20 2 30 3 40 4 50
Upvotes: 0
Reputation: 214949
Try re.sub
with a callback function that takes the next replacement from the list:
l = [10, 20, 30, 40, 50]
inp = "a b a d e"
import re
repl = iter(l)
result = re.sub(r'\w+', lambda m: str(next(repl)), inp)
Upvotes: 1