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

时间:2008-09-21 01:14:47

标签: ruby regex rar

要查看调用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兼容的regexp执行此操作的一种(有限的)方式是:

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

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

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

4 个答案:

答案 0 :(得分:4)

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

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

  

HEAD_FLAGS位标志:
  2个字节

     
    

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

  

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

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

答案 1 :(得分:3)

简短的回答是,无法构建单个正则表达式来满足您的问题。 Ruby 1.8没有外观断言(你的示例正则表达式中的?&lt;!stuff),这就是你的正则表达式不起作用的原因。这给你留下了两个选择。

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

答案 2 :(得分:0)

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

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

将“yes | no”替换为实际文件名。我将它与你的例子相匹配,看它是否只匹配第一组,因此正则表达式中的“是|否”。

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

答案 3 :(得分:0)

我个人不会在这种情况下使用(扩展)正则表达式(或者至少不是只使用一个表达式)。编码时出现了什么问题,例如,少数if s?