如果字符串包含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"
对于那些好奇的人,在我的应用程序中,我需要替换代码是由表驱动的 - 正则数据库和替换是从数据库中获取的。
答案 0 :(得分:9)
这很棘手。在Python中,替换文本反向引用未参与匹配are an error的组,因此我不得不使用lookahead assertions构建一个非常复杂的构造,但它似乎通过了所有测试用例:
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)
答案 1 :(得分:9)
试试这个简单的单线程,没有正则表达式,没有技巧:
a.replace("foo", "bar") + (a.count("foo") == 0) * "bar"
答案 2 :(得分:2)
答案 3 :(得分:1)
受@zenpoy启发的双线运动:
ar = a.replace("foo", "bar")
a + 'bar' if a is ar else ar
答案 4 :(得分:0)
难道你不能使用怪异的堂兄吗?
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))]
两者都不那么神秘,但与Tim's excellent regex solution相比,两者都有额外的函数调用和逻辑。