Question

The following

>>> re.sub(r'(\d+)', r'\1' * 2, 'test line 123')

gives

'test line 123123'

is there a way to make it give

'test line 246'

?

float() coercion doesn't work:

>>> re.sub(r'(\d+)', float(r'\1') * 2, 'test line 123')
could not convert string to float: \1

nor do eval or exec.

Was it helpful?

Solution

The second argument to re.sub() can also be a callable, which lets you do:

re.sub(r'(\d+)', lambda match:'%d' % (int(match.group(1))*2), 'test line 123')

BTW, there really is no reason to use float over int, as your regex does not include periods and will always be a non-negative integer

OTHER TIPS

The trick is to supply a function as the repl argument to re.sub():

In [7]: re.sub(r'(\d+)', lambda m:'%.0f'%(float(m.group(1))*2), 'test line 123') 
Out[7]: 'test line 246'

Each match is converted to float, doubled, and then converted to string using the appropriate format.

This can be simplified a little bit if the number is integer, but your question specifically mentions float, so that's what I've used.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top