1

要查看在哪个文件上调用 unrar 命令,需要确定哪个文件是文件集中的第一个文件。

以下是一些示例文件名,其中 - 自然地 - 只有第一组应该匹配:

yes.rar
yes.part1.rar
yes.part01.rar
yes.part001.rar

no.part2.rar
no.part02.rar
no.part002.rar
no.part011.rar

使用 PCRE 兼容的正则表达式的一种(有限)方法是:

.*(?:(?<!part\d\d\d|part\d\d|\d)\.rar|\.part0*1\.rar)

然而,当我在Rejax测试它时,这在 Ruby 中不起作用。

您将如何编写一个与 Ruby 兼容的正则表达式来仅匹配一组 RAR 文件中的第一个文件?

4

4 回答 4

4

不要依赖文件的名称来确定哪个是第一个。你最终会发现一个极端情况,你得到错误的文件。

RAR 的标题将告诉您哪个文件是卷中的第一个文件,假设它们是在最近的 RAR 版本中创建的。

HEAD_FLAGS 位标志:
2 个字节

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

因此,打开每个文件并检查 RAR 标头,专门寻找指示哪个文件是第一卷的标志。只要存档没有损坏,这永远不会失败。我已经对跨越 RAR 档案进行了自己的测试,并且根据上面的链接,它们的标题是正确的。

这是一种更安全的方法来确定哪个文件在这样的集合中首先出现。

于 2010-03-29T13:13:38.813 回答
3

简短的回答是,不可能构建一个单一的正则表达式来满足您的问题。Ruby 1.8 没有环视断言( (?<! 在您的示例正则表达式中的东西),这就是您的正则表达式不起作用的原因。这给您留下了两个选择。

1) 使用多个正则表达式来做到这一点。

def is_first_rar(filename)
    if ((filename =~ /part(\d+)\.rar$/) == nil)
        return (filename =~ /\.rar$/) != nil
    else
        return $1.to_i == 1
    end
end

2) 使用 ruby​​ 1.9, Oniguruma的正则表达式引擎。它支持环视断言,您可以将其安装为 ruby​​ 1.8 的 gem。之后,您可以执行以下操作:

def is_first_rar(filename)
    reg = Oniguruma::ORegexp.new('.*(?:(?<!part\d\d\d|part\d\d|\d)\.rar|\.part0*1\.rar)')
    match = reg.match(filename)
    return match != nil
end
于 2008-09-21T03:31:40.227 回答
0

我不是正则表达式专家,但这是我的尝试

^(yes|no)\.(rar|part0*1\.rar)$

将“yes|no”替换为实际文件名。我将它与您的示例进行了匹配,以查看它是否仅匹配第一组,因此正则表达式中的“是|否”。

更新:根据评论修复。不知道为什么用户不知道文件名所以我没有修复那个部分......

于 2008-09-21T03:08:24.493 回答
0

在这种情况下,我个人不会使用(扩展)正则表达式(或者至少不只是一个来完成这一切)。例如,在几个ifs 中编码有什么问题?

于 2008-09-21T03:09:18.423 回答