Reputation: 5931
I have a long string that contains placeholders, that should be replaced with some data.
strOut = "text text {{ }} text text {{ }}"
with this pattern
pattern = r'\{{(.+?)\}}'
It's easy for me to do something like this
pattern.sub(self.mymethod, strOut)
where mymethod will be called for substitution. It actually works great. However, this is the problem now. I need to replace all placeholders in string with the values from a list. For example, this is the string again:
strOut = "text text {{ }} text {{ }} text"
It will always have undetermined number of placeholders. If I also have a list of let's say 2 values
myList = [2, 3]
I need a way to inject these values into placeholders, and end up with this
"text text 2 text 3 text"
Number of values in a list and number of placeholder will always be the same, I just don't know in advance how many there will be.
Upvotes: 2
Views: 9631
Reputation: 89577
You can use format function and pass list with argument unpacking (*)
>>> myList = [2, 3]
>>> strOut = 'text text {} text {} text'
>>> print(strOut.format(*myList))
text text 2 text 3 text
Upvotes: 1
Reputation: 1389
my_csv = '%(first)s,%(last)s'
print my_csv % dict(last='Doe', first='John') # John,Doe
I like this for the following reasons :
inspired from https://stackoverflow.com/a/11023271/2147228
Upvotes: 7
Reputation: 142156
Sample code:
>>> strOut = "text text {{ }} text text {{ }}"
>>> pattern = r'\{{(.+?)\}}'
>>> import re
>>> re.findall(pattern, strOut)
[' ', ' ']
>>> items = iter(str(el) for el in [1, 2])
# as pointed out by @eyquem, this can also be written as:
# items = imap(str, [1, 2])
>>> re.sub(pattern, lambda L: next(items), strOut)
'text text 1 text text 2'
This will break if there's not enough parameters to meet the placeholders, but just ignore the remainder otherwise.
And if you're using 2.7+, you're laughing if you can get away with {}
as a place holder, as you can then just use 'text text {} text text {}'.format(*[1,2])
for instance
And for "fun"
(ab)using the lambda, you can do:
re.sub(pattern, lambda i, j=(str(el) for el in [1, 2]): next(j), strOut)
Upvotes: 3
Reputation: 8711
If there are no appearances of '{}'
(as opposed to '{{ }}'
) in your strOut
text, the following approach works. For strOut
and myList
as shown, the string it produces is 'text text 2 text 3 text'
.
strOut = "text text {{ }} text {{ }} text"
myList = [2, 3]
strOut.replace('{{ }}','{}').format(*myList)
Upvotes: 1
Reputation: 37259
You could try something like this (it uses the count
parameter of re.sub
):
In [1]: import re
In [2]: strOut = "text text {{ }} text text {{ }}"
In [3]: pattern = r'\{{(.+?)\}}'
In [4]: reduce(lambda x, y: re.sub(pattern, str(y), x, 1), [2, 3], strOut)
Out[4]: 'text text 2 text text 3'
Upvotes: 0