Regex для сопоставления с первым файлом в наборе файлов архива rar - PullRequest
3 голосов
/ 06 февраля 2010

Как мне это сделать? Я видел решение, не использующее единственное регулярное выражение для ruby, потому что ruby ​​не поддерживает ложные круглые утверждения. Но возможно ли это в 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 ]

5 голосов
/ 06 февраля 2010

Это должно пройти ваши тесты:

    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);
2 голосов
/ 06 февраля 2010

Вы можете сделать это в одном регулярном выражении, как в 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 мне кажется неуклюжей. В целом, я думаю, что приведенный выше код выражает намерение гораздо яснее, чем регулярное выражение.

Мне нравится, когда вы можете чисто решить проблему с помощью элегантного регулярного выражения, но я не уверен, что единственное регулярное выражение - лучший способ решить эту проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...