坚持使用正则表达式替换



我正在尝试替换"[!在字符串的开头仅带有"("。 "!]"也是如此带"(",仅在末尾。

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

正则表达式在匹配的"[!"、"!]"对之间的内容周围放置括号

# 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']

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

  • [!(
  • )代替!]

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

第一种方法

想想str.place是否可以完成这项工作。它看起来很方便,你甚至不需要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文档以了解正确的参数使用。

优雅

由于re.sub还支持反向引用,因此也可以替换成对的括号。

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

明智地选择!

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

逃避

请记住,反斜杠 (( 作为转义字符,必须在普通字符串文字中加倍,另一种方法是在字符串文字前面加上r。除最后一个示例外,将反斜杠(或r前缀(加倍是可选的,因为[]在python中没有功能,而1SOH(ASCII中的控制字符(或U+0001(Unicode点(的代码。

最新更新