Python replace string pattern with output of function

PythonRegex

Python Problem Overview


I have a string in Python, say The quick @red fox jumps over the @lame brown dog.

I'm trying to replace each of the words that begin with @ with the output of a function that takes the word as an argument.

def my_replace(match):
    return match + str(match.index('e'))

#Psuedo-code

string = "The quick @red fox jumps over the @lame brown dog."
string.replace('@%match', my_replace(match))

# Result
"The quick @red2 fox jumps over the @lame4 brown dog."

Is there a clever way to do this?

Python Solutions


Solution 1 - Python

You can pass a function to re.sub. The function will receive a match object as the argument, use .group() to extract the match as a string.

>>> def my_replace(match):
...     match = match.group()
...     return match + str(match.index('e'))
...
>>> string = "The quick @red fox jumps over the @lame brown dog."
>>> re.sub(r'@\w+', my_replace, string)
'The quick @red2 fox jumps over the @lame4 brown dog.'

Solution 2 - Python

I wasn't aware you could pass a function to a re.sub() either. Riffing on @Janne Karila's answer to solve a problem I had, the approach works for multiple capture groups, too.

import re

def my_replace(match):
    match1 = match.group(1)
    match2 = match.group(2)
    match2 = match2.replace('@', '')
    return u"{0:0.{1}f}".format(float(match1), int(match2))
    
string = 'The first number is 14.2@1, and the second number is 50.6@4.'
result = re.sub(r'([0-9]+.[0-9]+)(@[0-9]+)', my_replace, string)

print(result)

Output:

The first number is 14.2, and the second number is 50.6000.

This simple example requires all capture groups be present (no optional groups).

Solution 3 - Python

Try:

import re

match = re.compile(r"@\w+")
items = re.findall(match, string)
for item in items:
    string = string.replace(item, my_replace(item)

This will allow you to replace anything that starts with @ with whatever the output of your function is. I wasn't very clear if you need help with the function as well. Let me know if that's the case

Solution 4 - Python

A short one with regex and reduce:

>>> import re
>>> pat = r'@\w+'
>>> reduce(lambda s, m: s.replace(m, m + str(m.index('e'))), re.findall(pat, string), string)
'The quick @red2 fox jumps over the @lame4 brown dog.'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnathancahillView Question on Stackoverflow
Solution 1 - PythonJanne KarilaView Answer on Stackoverflow
Solution 2 - PythonDaveL17View Answer on Stackoverflow
Solution 3 - Pythonuser1689235View Answer on Stackoverflow
Solution 4 - PythonEmmanuelView Answer on Stackoverflow