EN VI

Python - Best way to use re.sub with a different behavior when first called?

2024-03-16 04:30:07
Python - Best way to use re.sub with a different behavior when first called

I'm trying to perform a number of replacements using re.sub(), except I want the first replacement to be different. One straightforward approach would be to run re.sub() twice with count = 1 for the first call, but because re.sub() allows for the repl argument to be a function, we can do this in a single call:

import re

def repl(matchobj):
    global first_sub
    if first_sub:
        first_sub = False
        print(f"Replacing '{matchobj.group()}' at {matchobj.start()} with ':)'")
        return ":)"
    else:
        print(f"Deleting '{matchobj.group()}' at {matchobj.start()}")
        return ""

text = "hello123 world456"
first_sub = True
text = re.sub(r"\d+", repl, text)

# Output:
#   Replacing '123' at 5 with ':)'
#   Deleting '456' at 14

Unfortunately, this makes use of global, which isn't great. Is there a better way to do this?

Solution:

With an iterator, inspired by Andrej:

import re

text = "hello123 world456"
text = re.sub(
    r"\d+",
    lambda _, i=iter([":)"]): next(i, ""),
    text
)
print(text)

Attempt This Online!

Or using a dict for the state:

import re

text = "hello123 world456"
text = re.sub(
    r"\d+",
    lambda m, d={0: ":)"}: d.pop(0, ""),
    text
)
print(text)

Attempt This Online!

Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login