Python Regex re.sub not working as intended with dictionary lookup function?

Question:

I have one Py file working as a lookup like (constants.py):

constants = {'[%IP%]':'0.0.0.0'}

From my main file, I’m trying to replace a part of my string using the lookup.

from constants import constants
import re
path = r"[%IP%]file.exe"
pattern = r'[%.*?%]'
def replace(match):
    return constants.get(match)
print(replace("[%IP%]")) # this bit works fine
print(re.sub(pattern, replace, path)) # this results in the matched pattern just vanishing

When I directly access the ‘replace’ function in my main file, it correctly outputs the matched result from the constants file dictionary.
But when I use the re.sub to substitute the pattern directly using the replace function with the lookup, it results in a string without the matched pattern at all.

So this is essentially the output for this (which isn’t correct):

0.0.0.0
file.exe

The desired output for this is:

0.0.0.0
0.0.0.0file.exe

Please help me fix this.

Asked By: Ankan Das

||

Answers:

The callback you pass to re.sub will be called with a Match object, not with a plain string. So the callback function needs to extract the string from that Match object.

Can be done like this:

def replace(match):
    return constants.get(match[0])
Answered By: trincot

The solution that I’ll mark as Accepted is definitely one solution.
The other way around is to use a lambda function and pass the parameters like:

re.sub(pattern, lambda x: replace(x.group()), path))
Answered By: Ankan Das