If a string contains foo, replace foo with bar. Otherwise, append bar to the string. How to write this with one single re.sub (or any other function) call? No conditions or other logic.
import re
regex = "????"
repl = "????"
assert re.sub(regex, repl, "a foo b") == "a bar b"
assert re.sub(regex, repl, "a foo b foo c") == "a bar b bar c"
assert re.sub(regex, repl, "afoob") == "abarb"
assert re.sub(regex, repl, "spam ... ham") == "spam ... hambar"
assert re.sub(regex, repl, "spam") == "spambar"
assert re.sub(regex, repl, "") == "bar"
For those curious, in my application I need the replacement code to be table-driven - regexes and replacements are taken from the database.
This is tricky. In Python, replacement text backreferences to groups that haven't participated in the match are an error, so I had to build quite a convoluted construction using lookahead assertions, but it seems to pass all the test cases:
result = re.sub("""(?sx)
( # Either match and capture in group 1:
^ # A match beginning at the start of the string
(?:(?!foo).)* # with all characters in the string unless foo intervenes
$ # until the end of the string.
| # OR
(?=foo) # The empty string right before "foo"
) # End of capturing group 1
(?:foo)? # Match foo if it's there, but don't capture it.""",
r"\1bar", subject)
Try this simple one-liner, no regexp, no tricks:
a.replace("foo", "bar") + (a.count("foo") == 0) * "bar"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With