Python replace string pattern with output of function

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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.'

Method 2

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 <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e9d8ddc7dba9d8">[email protected]</a>, and the second number is <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6a5f5a445c2a5e44">[email protected]</a>'
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).

Method 3

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

Method 4

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.'


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x