在Python中正则匹配rar压缩文件集合中的第一个文件

3 投票
3 回答
2093 浏览
提问于 2025-04-15 20:59

我需要解压一个文件夹里的所有文件,为此我需要找到这组文件中的第一个文件。目前我是在用一堆if语句和循环来实现这个功能。请问我能用正则表达式来做到这一点吗?

这是我需要匹配的文件列表:

yes.rar
yes.part1.rar
yes.part01.rar
yes.part001.rar
yes.r01
yes.r001

这些文件是不能被匹配的:

no.part2.rar
no.part02.rar
no.part002.rar
no.part011.rar
no.r002
no.r02

我在这个帖子上找到了一个类似的正则表达式,但似乎Python不支持可变长度的前瞻匹配。写一个单行的正则表达式会比较复杂,不过我会好好记录它,这没问题。这就是那种让你绞尽脑汁的问题。

提前谢谢大家。

:)

3 个回答

1

你确定要匹配这些情况吗?

yes.r01

这些文件不是第一个压缩包:.rar 文件总是第一个。

比如说,有 bla.rar、bla.r00,然后才是 bla.r01。如果你把 .r01 和 .rar 都当作第一个压缩包来提取文件,可能会导致文件被提取两次。

yes.r001

.r001 这个文件是不存在的。你是指 WinRAR 支持的 .001 文件吗?在 .r99 之后,应该是 .s00。如果这个文件存在,那可能是有人手动改名了。

理论上来说,按照文件名匹配应该和用 0x0100 标志来找到第一个压缩包一样可靠。

5

不要仅仅依靠文件名来判断哪个文件是第一个。这样做可能会遇到一些特殊情况,导致你找到错误的文件。

RAR的文件头会告诉你哪个文件是卷中的第一个,前提是这些文件是用比较新的RAR版本创建的。

HEAD_FLAGS 位标志:
2字节

0x0100 - 第一个卷(仅由RAR 3.0及更高版本设置)

所以你需要打开每个文件,查看RAR的文件头,特别是寻找那个标志,来判断哪个文件是第一个卷。只要压缩包没有损坏,这个方法是不会出错的。


更新: 我刚刚通过在十六进制编辑器中查看一些跨卷的压缩包确认了这一点。文件头的构造正如上面的链接所示。只需打开文件并读取头部的那个标志。带有那个标志的文件就是第一个卷。

3

其实不需要用到“向后查找”的这种方式。因为你是从字符串的开头开始查找的,所以你可以用“向前查找”来完成所有需要的操作,这样也能达到同样的效果。下面的代码应该可以用:

^((?!\.part(?!0*1\.rar$)\d+\.rar$).)*\.(?:rar|r?0*1)$

如果你想抓取文件名的第一部分,可以这样做:

^((?:(?!\.part\d+\.rar$).)*)\.(?:(?:part0*1\.)?rar|r?0*1)$

撰写回答