坚持正则表达式替换

Stuck with Regex Replace

我正在尝试替换“[!” 仅在字符串的开头带有“(”。 "!]" 和 ")" 也一样,只是在最后。

import re
l=["[!hdfjkhtxt.png!] abc", "hghjgfsdjhfg [a!=234]", "[![ITEM:15120710/1]/1587454425954.png!]", "abc"]
p=[re.sub("\[!\w+!]", '', l[i]) for i in range(len(l)) if l[i] != ""]
print(p)

要求的输出是

["(hdfjkhtxt.png)", "hghjgfsdjhfg [a!=234]", "([ITEM:15120710/1]/1587454425954.png)", "abc"]

您将您的任务描述为两部分的组合:

  • (
  • 代替[!
  • )代替!]

如果这可以单独完成或只能同时完成,稍后会解决。

第一种方法

想想 str.replace 是否可以胜任这项工作。看起来很方便,你甚至不需要 import re:

[e.replace("[!", "(").replace("!]", ")") for e in l]

顺便说一句:没有必要从替换中排除空字符串 (""),因为它已被正式替换为 "" 并且技术上无论如何都会被跳过。

正则表达式版本

[re.sub(r"\[!", "(", re.sub(r"!\]", ")", e)) for e in l]

分解

嵌套替换乍一看可能不像两步,所以看下面的例子

import re

l = [
    "[!hdfjkhtxt.png!] abc",
    "hghjgfsdjhfg [a!=234]",
    "[![ITEM:15120710/1]/1587454425954.png!]", 
    "abc"
]

for e in l:
    sd = re.sub(r"\[!", "(", e)
    sd = re.sub(r"!\]", ")", sd)
    print(e, " --> ", sd)

产生此输出:

[!hdfjkhtxt.png!] abc  -->  (hdfjkhtxt.png) abc
hghjgfsdjhfg [a!=234]  -->  hghjgfsdjhfg [a!=234]
[![ITEM:15120710/1]/1587454425954.png!]  -->  ([ITEM:15120710/1]/1587454425954.png)
abc  -->  abc

参见 re.sub documentation 以了解正确的参数使用。

细化

因为re.sub也支持向后引用,所以也可以替换成对的括号。

re.sub(r"\[!(.+)!\]", r"()", e)

明智地选择!

仔细阅读实际要求很重要。如果必须替换括号对,请使用第二个,如果无论出现是否配对都必须替换序列,请使用第一个。否则你做错了。

转义

请记住,作为转义字符的反斜杠 (\) 必须在普通字符串文字中加倍,另一种方法是在字符串文字前加上 r。双反斜杠(或 r 前缀)在除最后一个示例之外的所有示例中都是可选的,因为 \[\] 在 python 中没有功能,而 </code> 是<code>SOH (the control char in ASCII) or U+0001 (the Unicode point).

的代码

正则表达式在匹配的“[!”、“!]”对之间放置括号

# content between '[!' and '!]' in in capture group
[re.sub(r"\[!(.*)!\]", lambda m: "(" + m.group(1) + ")", s) for s in l]

输出

['(hdfjkhtxt.png) abc', 'hghjgfsdjhfg [a!=234]', '([ITEM:15120710/1]/1587454425954.png)', 'abc']