Is it possible to insert different values in a string based on the same matching pattern by using a list to specify the values to insert? I'm using python 3 and re.sub.
Here is what a mean:
line = "Float: __, string: __"
values = ["float", "string"]
newLine = re.sub('(_ )([.]_ )?',
(lambda m:
f'%'
f'{len(m.group(1))}'
f'{"." if values == "float" else ""}'
f'{(len(m.group(2) or ".")-1) if values == "float" else ""}'
f'{"f" if values == "float" else "s"}'),
line)
print(newLine)
Expected result:
Float: %2.0f, string: %2s
Actual result:
Float: %2s, string: %2s
Is it posssible to loop through the values list in order to get the correct result (this is not working and I get a TypeError)? Something like:
newLine = re.sub('(_ )([.]_ )?',
((lambda m:
f'%'
f'{len(m.group(1))}'
f'{"." if v == "float" else ""}'
f'{(len(m.group(2) or ".")-1) if v == "float" else ""}'
f'{"f" if v == "float" else "s"}') for v in values),
line)
Edit 1 The values list and the amount of matching patterns are always of same length.
CodePudding user response:
You cannot loop like this inside the repl
argument, but you can define a counter and pass it to the repl
function:
import re
line = "Float: __, string: __"
values = ["float", "string"]
obj = lambda:None
obj.i = -1
def repl(m, count, values):
count.i = 1
return f'%{len(m.group(1))}{"." if values[count.i] == "float" else ""}{(len(m.group(2) or ".")-1) if values[count.i] == "float" else ""}{"f" if values[count.i] == "float" else "s"}'
newLine = re.sub(r'(_ )(\._ )?',
lambda m: repl(m, obj, values),
line)
print(newLine)
## => Float: %2.0f, string: %2s
See the Python demo.
Here, an obj
object is declared, and its i
property is initialized with -1
. Then, inside the repl
function, its value is incremented and used as the index of the values
list.
Note that this approach works only if the number of matches equals the amount of items in the values
list.