Home > Mobile >  How to replace characters based on variables in a list using regex sub
How to replace characters based on variables in a list using regex sub

Time:06-17

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.

  • Related