2008-09-21 68 views
1

要查看要調用unrar命令的文件,需要確定哪個文件是文件集中的第一個文件。正則表達式僅匹配RAR文件集中的第一個文件

下面是一些示例文件名,其中 - 自然 - 只有第一組應該匹配:

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文件中的第一個文件?

+0

我以爲後續的rar文件有擴展名r01,r02,r03等等。 – paxdiablo 2008-09-21 01:17:12

+0

是的,有兩個命名方案是這個問題的根源。你要麼有.rar,.r01等,要麼part01.rar,part02.rar等 – Micke 2008-09-21 01:18:48

+0

Duplicate:http://stackoverflow.com/questions/2537882/ – 2012-07-04 09:07:07

回答

3

簡單的答案是,構建一個正則表達式來解決問題是不可能的。 Ruby 1.8沒有查找斷言(你的示例正則表達式中的(?<!),這就是爲什麼你的正則表達式不起作用。 。

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

2)使用正則表達式引擎紅寶石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 
0

我不是正則表達式的專家,但這裏是我的嘗試

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

替換「是|否」的實際文件名。我將它與您的示例進行了匹配,以查看它是否僅匹配第一組,因此正則表達式中的「是|否」。

更新:根據評論修正。不知道爲什麼用戶不知道文件名,所以我沒有修復該部分...

0

就我個人而言,我不會在這種情況下使用(擴展)的正則表達式(或至少不是一個做這一切) 。編碼這個有什麼問題,例如幾個if

4

不要依賴於文件的名稱,以確定哪一個是第一個。你最終會發現一個邊緣案例,你會得到錯誤的文件。

RAR's headers會告訴你哪個文件是捲上的第一個文件,假設它們是在RAR的新版本中創建的。

HEAD_FLAGS位標誌:
2個字節

0100 - 第一冊(只有RAR 3.0及更高版本設置)

所以打開每個文件並檢查RAR頭文件,專門查找指示哪個文件是第一個卷的標誌。只要檔案沒有損壞,這永遠不會失敗。根據上面的鏈接,我已經完成了我自己的測試,使用RAR壓縮文件並且它們的頭文件是正確的。

這是一個確定哪個文件是第一個在這樣的集合中的更安全的方法。

相關問題