Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular expression replace with self

Tags:

python

regex

I am using regular expressions to tag information in messages. These messages are structured in that certain pieces of information I am looking for are ordered. The order however for certain messages as well as the specific types of information I am looking for can change depending on the type of message. Below is a minimal example of such a message

message = 'foo 1234567890 bar'

Suppose I know my message to consist of 3 pieces of information I am looking for, var_a, var_b, and var_c. I know that var_a and var_c are lowercase strings while var_b is a number and that they appear in the order var_a, var_b, and then var_c in my message. I can tag them using

r = re.compile('(?P<var_a>[a-z]*)\s+(?P<var_b>[0-9]*)\s+(?P<var_c>[a-z]*)')
d = [m.groupdict() for m in r.finditer(message)][0]

for key, value in d.items():
    message = message.replace(value, f'[{key}]{value}[{key}]')

output

'[var_a]foo[var_a] [var_b]1234567890[var_b] [var_c]bar[var_c]'

However when I have duplicate words in my messages between for example var_a and var_c, i.e.

message = 'foo 1234567890 foo'

I get as ouput

'[var_a][var_c]foo[var_c][var_a] [var_b]1234567890[var_b] [var_a][var_c]foo[var_c][var_a]'

How would I go about dealing with this? I thought about immediately replacing the phrases during the regular expression matching (using something like re.sub) but I can't seem to figure out how to do this because I need to be able to reference both the names I'm using in my regular expression (like var_a etc.) as well as the content assigned to these names.

The output I would like to obtain is

'[var_a]foo[var_a] [var_b]1234567890[var_b] [var_c]foo[var_c]'

This includes the spaces (or for that matter any other kind of text from the original message).

like image 656
DisneylandSC Avatar asked Sep 26 '26 14:09

DisneylandSC


1 Answers

I would use re.sub here as:

message = 'foo 1234567890 bar'
output = re.sub(r'\b([a-z]+) (\d+) ([a-z]+)\b', '[var_a]\\1[var_a] [var_b]\\2[var_b] [var_c]\\3[var_c]', message)
print(output)

This prints:

[var_a]foo[var_a] [var_b]1234567890[var_b] [var_c]bar[var_c]
like image 57
Tim Biegeleisen Avatar answered Sep 28 '26 04:09

Tim Biegeleisen