解析这种字符串模式最干净的方法?

时间:2009-07-28 20:05:37

标签: c# .net regex string parsing

我有音乐文件名,如:

Gorillaz (2001)
Gorillaz (7th State Mix) (2002)
Gorillaz (2001) (Featuring Travis)
Gorillaz (1Mix) (2003)
Gorillaz (1000) (2001)

如何以最干净,最简单的方式解析年份?

现在我通过查找每个'('来解析它们,然后确保()之间的字符数为4,第一个字符为1或2,并且可以使用{{来解析它们1}}?

我可以使用单个Regex解析这些类型的字符串吗?


编辑:

年份最长可达50-60岁,因此不超过1950年。

5 个答案:

答案 0 :(得分:8)

我认为这就是您所追求的目标:

using System;
using System.Text.RegularExpressions;

class Test
{
    static void Main()
    {
        string[] samples = new[] { "Gorillaz (2001)",
                "Gorillaz (7th State Mix) (2002)",
                "Gorillaz (2001) (Featuring Travis)",
                "Two matches: (2002) (1950)",
                "Gorillaz (1Mix) (1952)",
                "Gorillaz (1Mix) (2003)",
                "Gorillaz (1000) (2001)" };

        foreach (string name in samples)
        {
            ShowMatches(name);
        }
    }

    static readonly Regex YearRegex = new Regex(@"\((19[5-9]\d|200\d)\)");

    static void ShowMatches(string name)
    {
        Console.WriteLine("Matches for: {0}", name);
        foreach (Match match in YearRegex.Matches(name))
        {
            Console.WriteLine(match.Value);
        }
    }
}

这将有效至2009年。为了使其超越,请使用@“((19 [5-9] \ d | 20 [01] \ d))”等。

请注意,仍会打印括号 - 您可以使用组构造删除它们,但我个人只是使​​用Substring:)

答案 1 :(得分:2)

此正则表达式将匹配您的模式:

@"\(([12]\d{3})\)"

然后,您可以提取第1组以获得年份。然后,您可以使用Convert.ToInt32将年份作为int,并检查它是否大于1950(最好将此作为数字比较,而不是使正则表达式过度复杂化。)

答案 2 :(得分:1)

你应该能够使用正则表达式来匹配它。 以下是您可能尝试使用的模式:

\([12][0-9]{3}\)

别忘了启用贪婪。这也将匹配最后一行的(1000)。这也需要吗?

修改

 \((19|20)[0-9]{2}\)
如果您不希望将(1000)作为匹配

将完成这项工作

问候

答案 3 :(得分:1)

考虑到你的东西看起来像几年但不是(1000)如果你认为你的节目会在一段时间内出现,我会寻找19 **,20 **,也许是21 **:)

/\(19\d\d|20\d\d|21\d\d\)/

对于您的输入,这给出了:

2001
2002
2001
2003
2001
2001

答案 4 :(得分:0)

看起来很棘手,除非我们了解更多关于这些括号的内容:如果你的“(1000)”不是真的一年,你可能会有一个“(2000)”而不是真的一年也。我在谈论你样本中的最后一行:

  

Gorillaz(1000)(2001)

如果这是有效的,为什么不这样呢? :

  

Gorillaz(2000)(2001)

后一个示例中的(2000)与前者(1000)的概念角色相同(不是一年)。你的正则表达式将如何知道哪一年?如果您知道这不会发生,如何你现在不会发生?