如何解析字符串以提取年份范围值?

时间:2010-11-04 00:28:21

标签: c# algorithm string

我收到了变更请求,我不确定如何最好地接近它。如果客户端搜索某些内容并且指定的年份或年份范围大于我们在数据库中的范围,则必须返回与我们最近年份范围相对应的结果。

目前我们在db中的结果都遵循以下模式之一:

Thing1 Thing2 S1 // There's some results with no year
Thing1 Thing2 2006-07 Series 6 // there's some results with 'Series X'
Thing1 Thing2 2006-2007 S12 RP // some resuls have SN or SN YZ
Thing1 Thing2 2020-21 S6 // some results don't have a full second year
Thing1 Thing2 2022-2024 S12
Thing1 Thing2 2024 Onwards // the result that matches the final year just has the year & 'Onwards'

世界上有更多的Thing1 Thing2可供使用,最高可达2060年,但我们只保留了+ 14年的数据,因为14年后(比如2026年或2028年),数据与几年前。

我们拥有的最大年份,存在的最长年限每2年增加2年。所以在2012年,我们将有Thing1 Thing2 2026以上,并且存在的最大值将是2062年。

所以基本上,我需要确定客户端何时搜索[Thing1(或)Thing2的年份范围],如果第一年的值大于[今年+ 14],我必须返回[今年+ 14],但只有当年是偶数年,否则我必须返回[今年+ 13]。

我遇到的麻烦是如何识别一个不符合明确定义模式的字符串中间的年份,除了年份的第一部分以4位数年份开始。

对我来说,最好的方法是什么?有人可以建议我如何解决这个问题吗?感谢。

3 个答案:

答案 0 :(得分:1)

这种正则表达式模式可以很好地运行:\b(?<Year1>\d{4})(?:-(?<Year2>\d{2,4}))?\b

说明:

  • \b:是一个词边界,以确保我们完全靠自己捕捉年份,而不是作为另一个词的一部分(即,没有部分匹配) - 这用于锚定两端的图案
  • (?<Year1>\d{4}):命名捕获组以匹配4位数字
  • (-(?<Year2>\d{2,4}))?:这与-短划线匹配,然后在第2年使用命名捕获组,匹配2-4个重复数字,因为这些年份的长度不同。开始和结束括号将此模式组合在一起,最后尾随?使整个组成为第二年不存在的情况下的可选项。

从技术上讲,\d{2,4}部分接受07, 107 ,2007。显然,3位数年份不正确。我建议您执行其他错误检查以捕获此类方案。您可以通过将其更改为\d{2}|\d{4}来阻止它,但是您将匹配Year1而不是Year2并丢失用户输入。

以下是代码:

string[] inputs = { "Thing1 Thing2 S1", "Thing1 Thing2 2006-07 Series 6", "Thing1 Thing2 2006-2007 S12 RP", "Thing1 Thing2 2020-21 S6", "Thing1 Thing2 2022-2024 S12", "Thing1 Thing2 2024 Onwards" };
string pattern = @"\b(?<Year1>\d{4})(-(?<Year2>\d{2,4}))?\b";
Regex rx = new Regex(pattern);

foreach (var input in inputs)
{
    Match m = rx.Match(input);
    Console.WriteLine("{0}: {1}", m.Success, input);
    if (m.Success)
    {
        string year1 = m.Groups["Year1"].Value;
        string year2 = m.Groups["Year2"].Value;
        Console.WriteLine("Year1: {0}, Year2: {1}", year1, year2 == "" ? "N/A" : year2);
    }
    Console.WriteLine();
}

答案 1 :(得分:0)

也许只是在字符串中搜索前4个数字字符(如果有的话)并将它们当作年份来处理它?<​​/ p>

答案 2 :(得分:0)

或像

这样的正则表达式
perl -ne '/(\d\d\d\d)-(\d\d(\d\d)?)/; print "$1:$2:$3"'