Подтвердить что ты не робот

Замените x на y или добавьте y, если нет x

Если строка содержит foo, замените foo на bar. В противном случае добавьте bar в строку. Как написать это с помощью одного вызова re.sub (или любой другой функции)? Никаких условий или другой логики.

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"

Для тех, кому интересно, в моем приложении мне нужен код замены для управления таблицами - регулярные выражения и замены берутся из базы данных.

4b9b3361

Ответ 1

Это сложно. В Python замена текстовых обратных ссылок на группы, которые не участвовали в матче является ошибкой, поэтому мне пришлось построить довольно сложную конструкцию, используя утверждения lookahead, но, похоже, все тестовые примеры:

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 there, but don't capture it.""", 
                     r"\1bar", subject)

Ответ 2

Попробуйте этот простой однострочный, без регулярных выражений, без трюков:

a.replace("foo", "bar") + (a.count("foo") == 0) * "bar"

Ответ 3

Вы можете сделать это

регулярное выражение:

^(?!.*foo)(.*)$|foo(\b)

или

foo|^(?!.*foo)(.*)$

заменить на: \1bar

работает здесь

Ответ 4

Два лайнера, вдохновленные @zenpoy:

ar =  a.replace("foo", "bar") 
a + 'bar' if a is ar else ar

Ответ 5

Разве ты не можешь использовать странного кузена?

re.sub(regex, repl, str) if re.match(regex,str) else str + repl

Или жирный кузен?

(str + repl, re.sub(regex, repl, str))[bool(re.match(regex, str))]

Оба являются менее загадочными, хотя, по общему признанию, оба имеют дополнительные вызовы функций и логику по сравнению с отличным регулярным выражением Тима.