Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用y替换x,如果没有x,则追加y_Python_Regex - Fatal编程技术网

Python 用y替换x,如果没有x,则追加y

Python 用y替换x,如果没有x,则追加y,python,regex,Python,Regex,如果字符串包含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.s

如果字符串包含
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"
对于那些好奇的人,在我的应用程序中,我需要表驱动的替换代码-正则表达式和替换从数据库中获取。

您可以这样做

正则表达式:

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

替换为:
\1bar


工作

这很棘手。在Python中,替换文本反向引用了未参与匹配的组,因此我不得不使用构建一个相当复杂的构造,但它似乎通过了所有测试用例:

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)

试试这个简单的单行程序,没有regexp,没有技巧:

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

灵感源自@zenpoy的双衬里:

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

你不能用那个奇怪的表哥吗

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))]


两者都不那么神秘,尽管无可否认,两者都有额外的函数调用和逻辑。

难道“x或不是x”不代替一切吗?@Anirudh:又增加了一个例子,这取决于它有多复杂,以及你最终尝试扩展正则表达式的程度,你也可以考虑存储代码对象而不是使用它。当“Foo”不被空间包围时,“AfooCuk”怎么样?@双下拉:空格无所谓。这在字符串上失败,有多个词,如<代码> 123代码>(结果:<代码>单杠双杠三栏< /代码>)。我总是删除我的下票,当它的原因消失的时候。现在,你的答案与@Tim删除版本中的答案非常相似。他提到他在某些情况下犯了错误,我不知道可能是什么,希望他能在有空的时候回到这个问题上来,解释他的边缘情况……蒂姆是这里的第一位正则表达式回答者,如果他发布了一个答案,这是正常工作的。我试过他的答案,就像我试过你的一样。如果在链接中的
$
之后添加了您忘记的缺少的结束括号,那么它也适用于您。@Anirudh,OP的问题被标记为
python
。此外,我看到您的解决方案执行了组替换,但没有为输入字符串中的
foo
功能定义捕获组。@Anirudh不幸的是,它没有定义捕获组,因为
\1
总是指
(.*)
,而
\2
则指
(\b)
.Oops,我在某些情况下会出错。我得做这件事,但我现在得去听讲座。稍后…抱歉花了这么长时间。这是一个非常有趣的问题。谢谢<代码>^((?:(?!foo)。)*)(?:foo)?是您所需要的全部。当第一个部分没有匹配的内容时,下一个部分只能是
foo
或字符串的结尾。@Alanmore:你说得对,但前提是字符串中只有一个
foo
。也许没有
^
…让我检查一下…不,那不行。嗯,我应该更仔细地看一下示例。这个问题并没有暗示可能有不止一个
foo
;有些情况下正则表达式不是最好的工具——这就是其中之一。不幸的是,他似乎确实需要一个正则表达式(见他问题的最后一句)。@TimPietzcker——因此他可以为此定义一个函数:
def my_nonre_sub(x,y,z):返回z.replace(x,y)+(z.count(x)==0)*y
为什么要进行向下投票?OP要求使用regex“或任何其他函数”,这应该是:
a+'bar',如果a是a.replace(“foo”,“bar”),则为a.replace(“foo”,“bar”)
这是调用replace两次…@zenpoy,谢谢,我本来有一个两行程序,但过度优化了它。
(str + repl, re.sub(regex, repl, str))[bool(re.match(regex, str))]