正则表达式匹配rar存档文件集中的第一个文件

时间:2010-02-06 13:36:33

标签: c# regex

我该怎么做?我已经看到了一个解决方案,不使用单个正则表达式ruby因为ruby不支持loookaround断言。但是在c#中是否可能?

[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);
}

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:2)

你可以用一个正则表达式来做,无论是在C#还是在Ruby中,但为什么要这么麻烦?

你还没有真正定义你想要的东西 - 首先你应该记录下来。一旦你记录下来,很容易将该描述转换为普通代码。我认为它更具可读性和维护性:

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

我在那里留下了一个正则表达式,因为它不太复杂,而且摆弄Path函数的替代方法对我来说似乎很笨拙。总的来说,我认为上面的代码比正则表达式更清楚地表达了意图。

当你能用优雅的正则表达式干净地解决问题时,我确实喜欢它,但我不确定单个正则表达式是解决这个问题的最佳方法。