Python 正则表达式否定元字符
Python中的元字符否定。
我在网上查了很多资料,试了几种不同的写法,现在想不出其他办法了。
我想给一些文件重命名。这些文件的标题里有年份,比如说[2002]。但有些文件没有方括号,我想把它们都加上。
所以我想找一个正则表达式(最好能编译的),在我脑海中,它看起来像(^[\d4^])
,因为我想找到一组没有方括号的四个数字。我用方括号是希望能把它们绑定在一起,这样我就可以用类似[\1]
的方式来重命名。
1 个回答
9
如果你想检查某个模式周围的内容,可以使用 前瞻 和 后顾 断言。这些并不是匹配的一部分,而是告诉你期望在匹配的内容周围找到什么(或者不找到什么)。
因为我们不想要括号,所以需要使用 负向 后顾和前瞻。
负向前瞻的写法是 (?!...)
,它的意思是如果 ...
后面没有出现,就会匹配。负向后顾的写法是 (?<!...)
,它的意思是如果 ...
前面没有出现,就会匹配。
我们的例子稍微复杂一点,因为我们使用了 [
和 ]
,这两个符号在正则表达式中有特殊含义,所以我们需要用 \
来转义它们。
所以我们可以这样构建一个模式:
- 对
[
的负向后顾 -(?<!\[)
- 四个数字 -
\d{4}
- 对
]
的负向前瞻 -(?!\])
这给我们带来了以下的 Python 代码:
>>> import re
>>> r = re.compile("(?<!\[)\d{4}(?!\])")
>>> r.match(" 2011 ")
>>> r.search(" 2011 ")
<_sre.SRE_Match object at 0x10884de00>
>>> r.search("[2011]")
要重命名,你可以使用 这个 re.sub
函数,或者在你编译的模式上使用 sub
函数。为了让它正常工作,你需要在年份周围加一对额外的括号,把它标记为一个组。
另外,在指定替换内容时,你需要用 \1
来引用这个组,所以你必须转义 \
,或者使用原始字符串。
>>> r = re.compile("(?<!\[)(\d{4})(?!\])")
>>> name = "2011 - This Year"
>>> r.sub(r"[\1]",name)
'[2011] - This Year'