2010-02-06 2 views
3

Comment faire? J'ai vu une solution n'utilisant pas une seule regex pour ruby ​​becauase ruby ​​ne supporte pas les assertions loookaround. Mais est-ce possible en C#?Regex pour faire correspondre le premier fichier dans un ensemble de fichiers d'archive 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); 
} 

Répondre

5

Cela devrait passer vos tests:

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

C'est exactement ce que je voulais, merci! J'ai essayé presque la même chose dans différents combos mais je ne pouvais pas le faire fonctionner, mais cela fonctionne parfaitement! J'ai besoin d'aiguiser un peu mes compétences en regex! – MatteS

2

Vous pouvez le faire en une seule expression régulière, à la fois en C# et en Ruby, mais à quoi bon?

Vous n'avez pas vraiment défini exactement ce que vous voulez - d'abord vous devriez documenter cela. Une fois que vous l'avez documenté, il est facile de transformer cette description en code ordinaire. Je pense qu'il est plus lisible et maintable ainsi:

/// <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"; 
} 

J'ai laissé une expression régulière là-bas car il est pas trop complexe, et l'alternative de jongler avec les fonctions de chemin semble maladroit pour moi. Dans l'ensemble, je pense que le code ci-dessus exprime l'intention beaucoup plus clairement qu'une expression régulière.

Je l'aime quand vous pouvez résoudre correctement un problème avec une expression régulière élégante, mais je ne suis pas sûr qu'une seule expression régulière est la meilleure façon de résoudre ce problème.

+0

J'ai trouvé cette question, donc je n'étais pas sûr si cela pouvait être fait: http://stackoverflow.com/questions/109916/regular-expression-to-match-only-the-first-file-in-a-rar- file-set Je suppose que c'est une question de goût entre décrire ce que vous voulez dans le code ou décrire la regex en utilisant un test. Im utilisant la fonction principalement dans les requêtes linq un peu comme: var file = from f dans Directory.GetFiles (chemin) où RarFirstFileRegex.IsMatch (f); – MatteS

Questions connexes