2010-02-06 19 views
3

我該怎麼做?我見過一個解決方案不使用一個正則表達式的ruby,因爲ruby不支持loookaround斷言。但是,它可能在C#中?正則表達式匹配rar檔案文件集中的第一個文件

[Test] 
public void RarArchiveFirstFileNameShouldMatch() { 
    var regex = new Regex(@"\.(rar|001)$", RegexOptions.IgnoreCase | RegexOptions.Singleline); 
    Assert.That(regex.IsMatch("filename.001")); 
    Assert.That(regex.IsMatch("filename.rar")); 
    Assert.That(regex.IsMatch("filename.part1.rar")); 
    Assert.That(regex.IsMatch("filename.part01.rar")); 
    Assert.That(regex.IsMatch("filenamepart44.rar")); 
    Assert.That(regex.IsMatch("filename.004"), Is.False); 
    Assert.That(regex.IsMatch("filename.057"), Is.False); 
    Assert.That(regex.IsMatch("filename.r67"), Is.False); 
    Assert.That(regex.IsMatch("filename.s89"), Is.False); 
    Assert.That(regex.IsMatch("filename.part2.rar"), Is.False); 
    Assert.That(regex.IsMatch("filename.part04.rar"), Is.False); 
    Assert.That(regex.IsMatch("filename.part11.rar"), Is.False); 
} 

回答

5

這應該通過你的測試:

var regex = new Regex(@"(\.001|\.part0*1\.rar|^((?!part\d*\.rar$).)*\.rar)$", RegexOptions.IgnoreCase | RegexOptions.Singleline); 
    Assert.That(regex.IsMatch("filename.001")); 
    Assert.That(regex.IsMatch("filename.rar")); 
    Assert.That(regex.IsMatch("filename.part1.rar")); 
    Assert.That(regex.IsMatch("filename.part01.rar")); 
    Assert.That(regex.IsMatch("filename.004"), Is.False); 
    Assert.That(regex.IsMatch("filename.057"), Is.False); 
    Assert.That(regex.IsMatch("filename.r67"), Is.False); 
    Assert.That(regex.IsMatch("filename.s89"), Is.False); 
    Assert.That(regex.IsMatch("filename.part2.rar"), Is.False); 
    Assert.That(regex.IsMatch("filename.part04.rar"), Is.False); 
    Assert.That(regex.IsMatch("filename.part11.rar"), Is.False); 
+0

這正是我想要的,謝謝!我在不同的組合中嘗試了幾乎相同的東西,但是我無法使其工作,但是這種方式非常完美!我需要提高我的正則表達式技能! – MatteS 2010-02-06 18:59:31

2

你能做到在一個正則表達式,無論是在C#和紅寶石,但何必呢?

你還沒有真正定義你想要的東西 - 首先你應該記錄它。一旦你記錄了它,很容易將該描述轉換爲普通的代碼。我認爲這是更具可讀性和maintable這樣:

/// <summary> 
/// Returns true if a filename's extension is .001. 
/// If the extensions is .rar, check to see if there is a part number 
/// immediately before the extension. 
/// If there is no part number, return true. 
/// If there is a part number, returns true if the part number is 1. 
/// In all other cases, return false. 
/// </summary> 
static bool isMainFile(string name) 
{ 
    string extension = Path.GetExtension(name); 
    if (extension == ".001") 
     return true; 
    if (extension != ".rar") 
     return false; 
    Match match = Regex.Match(name, @"\.part(\d+)\.rar$"); 
    if (!match.Success) 
     return true; 
    string partNumber = match.Groups[1].Value.TrimStart('0'); 
    return partNumber == "1"; 
} 

我在離開一個正則表達式有,因爲它不是太複雜,並與路徑功能擺弄的替代笨重,似乎對我。總體而言,我認爲上述代碼比正則表達式更清楚地表達意圖。

我喜歡它,當你可以用優雅的正則表達式乾淨地解決問題時,但我不確定單個正則表達式是解決此問題的最佳方法。

+0

我發現這個問題,因此我不能確定它是否可以完成:http://stackoverflow.com/questions/109916/regular-expression-to-match-only-the-first-file-in-a-rar-文件集 我想它是一個味道之間的問題描述你想要的代碼或描述正則表達式使用測試。 我使用函數主要在linq查詢有點像: var file = from f in Directory.GetFiles(path)where RarFirstFileRegex.IsMatch(f); – MatteS 2010-02-06 19:04:15