代码之家  ›  专栏  ›  技术社区  ›  Micke

正则表达式仅匹配RAR文件集中的第一个文件

  •  1
  • Micke  · 技术社区  · 18 年前

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

    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)
    

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

    你会怎么写 红宝石兼容

    4 回复  |  直到 18 年前
        1
  •  4
  •   Welbog    16 年前

    不要依赖文件名来确定哪一个是第一个。你最终会发现一个边缘案例,在那里你得到了错误的文件。

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

    头标志位标志:
    2字节

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

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

        2
  •  3
  •   bmdhacks    18 年前

    简单的回答是,不可能构造一个正则表达式来满足您的问题。Ruby1.8没有lookaround断言(示例regex中的(?<!东西),这就是为什么您的regex不工作的原因。

    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 . 它支持lookaround断言,您可以 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
  •  0
  •   mweerden    18 年前

    就我个人而言,在这种情况下,我不会使用(扩展的)正则表达式(或者至少不会只使用一个正则表达式来完成这一切)。例如,将其编码为几行有什么问题 if s

        4
  •  0
  •   Matthew Encinas    18 年前

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

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

    更新:根据注释修复。不知道为什么用户不知道文件名,所以我没有修复该部分。。。

    推荐文章