首页 > 解决方案 > 卡住了正则表达式替换

问题描述

我正在尝试替换“[!” 仅在字符串的开头带有“(”。对于带有“)”的“!]”也是如此,仅在结尾处。

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

标签: pythonre

解决方案


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

  • 替换[!(and
  • 替换!]).

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

第一种方法

想想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文档以了解正确的参数使用。

细化

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

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

做出明智的选择!

仔细阅读实际需求很重要。如果您必须替换括号对,请使用第二个,如果您必须替换序列而不管匹配与否,请使用第一个。否则你做错了。

逃跑

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


推荐阅读