【问题标题】:Regular expression to match only the first file in a RAR file set正则表达式仅匹配 RAR 文件集中的第一个文件
【发布时间】:2010-09-11 17:09:39
【问题描述】:

要查看在哪个文件上调用 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 文件中的第一个文件?

【问题讨论】:

  • 我以为后续的rar文件有扩展名r01、r02、r03等等。
  • 是的,有两种命名方案是这个问题的根源。您要么拥有 .rar、.r01 等,要么拥有 part01.rar、part02.rar 等。

标签: ruby regex rar


【解决方案1】:

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

RAR's headers 会告诉您哪个文件是卷中的第一个文件,假设它们是在较新版本的 RAR 中创建的。

HEAD_FLAGS 位标志:
2个字节

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

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

这是一种非常安全的方法来确定哪个文件在这样的集合中是第一个。

【讨论】:

    【解决方案2】:

    简短的回答是,不可能构建单个正则表达式来满足您的问题。 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。它支持环视断言,你可以install it as a gem for ruby 1.8。之后,您可以执行以下操作:

    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
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 这没有错,这正是我在问问题之前解决它的方式。但是你知道,一旦你尝试了某件事却无法弄清楚,你真的很想知道它应该怎么做。
      【解决方案4】:

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

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

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

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

      【讨论】:

      • 这也接受“no.part21.rar”;您可能想要“0”而不是“[^1]”。另外,我怀疑文件名是事先知道的。
      • 不幸的是,没有办法知道用户可能会为他们的文件命名。不过,可以通过将正则表达式更改为 ^\D+\.(rar|part0*1\.rar)$ 来捕获更多文件名,但如果用户在文件名中确实有数字,则它会再次回到正方形.
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-07
      • 2015-06-25
      • 2023-03-17
      • 1970-01-01
      相关资源
      最近更新 更多