如何从字符串中获取年份?

时间:2014-03-20 17:28:07

标签: c# regex

如何获得以下可能字符串的年份:

"01/01/2003" 
"01/01/03" 
"01-01-03" 
"01-01-2003." 
"Jenuary 01, 2003" 
"Jenuary 01, 03" 
"01 Jen 03" 
"01 jen 2003" 
"Jenuary 01, 2003." 
"Jenuary 01, of 2003."
"01/01/03" 

我如何获得03或2003 唯一的规则是:

  1. 年份在字符串
  2. 的末尾
  3. 字符串可以以"结尾。"或空格或其他角色,然后忽略它
  4. 一年的长度可以是2或4
  5. 分隔符可以是" /"," space"和" - "
  6. 我只能得到以下表达式

    Regex.Match("Jenuary 01, 2003.", @"[^/|^-|^ ]+$").Value
    

    但我遇到了带来额外字符的问题

    "Jenuary 01, 2003." I get "2003."
    

    提前致谢

8 个答案:

答案 0 :(得分:2)

如果你真的需要使用正则表达式,这个模式应该适合你:

^.+[-/ ](\d+)\.?$

然后替换为\1

答案 1 :(得分:2)

您可以使用LINQ。根据您的规则,这应该有效:

var year = input.Split(' ','/','-').Last();

更一般地说:

 var dates = new List<string>()
        {
            "01/01/2003",
            "01/01/03",
            "01-01-03",
            "01-01-2003.",
            "Jenuary 01, 2003",
            "Jenuary 01, 03",
            "01 Jen 03",
            "01 jen 2003",
            "Jenuary 01, 2003.",
            "01/01/03"
        };

var years = dates.Select(x => x.Split(' ', '/', '-').Last());

以下是LINQPad中的生成结果:

enter image description here

为了忽略非数字字符,您可以这样做:

var years = dates
          .Select(x => new string(x.Split(' ', '/', '-').Last()
          .Where(char.IsDigit).ToArray()));

答案 2 :(得分:1)

var date = DateTime.Parse(theString);
var year = date.Year;

我确信有更好的方式来解释文化,但你可以这样做:

var adjustedDate = theString.Replace("Jen", "Jan").Replace("jen", "Jan");
var date = DateTime.Parse(adjustedDate);
var year = date.Year;

答案 3 :(得分:1)

这应该有效:

  1. 确定分隔符
  2. 拆分分隔符上的字符串
  3. 抓住最后一个元素(年)
  4. 仅采用数字字符
  5. 这看起来像这样:

    char[] separators = new char[] { '/', '-', ' ' };
    
    //using LINQ
    string year = myString.Split(separators).Last().TakeWhile(c => char.IsDigit(c)).ToString();
    

    使用.Split将获得一个字符串数组,这些字符串是在分隔符处拆分的原始字符串的组件。 .Last会给你最后一个字符串。

    字符串可以被视为char的数组,因此我们可以使用TakeWhile在某个条件成立时从数组的开头获取字符(char是一个数字)。由于这为我们提供了char个数组,因此我们需要使用ToString()使其成为字符串。

答案 4 :(得分:1)

这是正则表达式:

[ -\/](\d{2}|\d{4})[^\d]?$

[ -\/]表示可以是空格, - 或/

(\d{2}|\d{4})表示2位或4位

[^\d]?除了数字之外的任何可选字符。

$是字符串的结尾。

更新:如果您不想选择第1组,请使用以下内容:

(?<=[ -\/])(\d{2}|\d{4})(?=[^\d]?$)

答案 5 :(得分:1)

足够简单:

\b(?:\d{2}|\d{4})(?=\D*$)

不知道#4的含义,因为你没有询问日期格式验证,只是从日期字符串中提取长度为2或4个字符的最后一个数字(上面的RegEx完全确实如此)。 / p>

答案 6 :(得分:1)

由于所有年份都在字符串的末尾,因此使用正则表达式选项RightToLeft轻松 获取它们。要处理空格或句点(或任何其他非数字),请使用 not [^\d]集合来忽略任何非数字,其中(\d+)[^\d]?表示任何字符一个数字。

然后像往常一样形成从左到右阅读的模式。所以我们希望年份数字后跟非数字匹配。因此是模式:

(\d+)

解释的是:捕获组[^\d]?将使用所有数字,后跟可能的非数字right to left。当使用var data = new string[] { "01/01/2003", "01/01/03", "01-01-03", "01-01-2003.", "Jenuary 01, 2003", "Jenuary 01, 03", "01 Jen 03", "01 jen 2003", "Jenuary 01, 2003.", "Jenuary 01, of 2003.", "01/01/03", }; data.Select (dt => Regex.Match(dt, @"(\d+)[^\d]?", RegexOptions.RightToLeft).Groups[1].Value) .ToList() .ForEach( year => Console.WriteLine( year )); /* Output 2003 03 03 2003 2003 03 03 2003 2003 2003 03 */ 选项运行时,正则表达式解析器将从左到右模式展开为从右到左,并反向解析输入文本。

亲眼看看:

{{1}}

答案 7 :(得分:1)

您可以使用正则表达式执行任务:

    public static int ObtainYear(String value) {
      if (String.IsNullOrEmpty(value))
        throw new ArgumentNullException("value");

      // two ou four digits possibly followed by any spaces and/or dots
      Match match = Regex.Match(value, @"(\d{2}|\d{4})(\.| )*$");

      if (!match.Success) 
        throw new ArgumentException("value");

      int year = int.Parse(match.Groups[0].Value.Trim(' ', '.'), CultureInfo.InvariantCulture);

      // If you get two digits year you should add either 1900 or 2000
      if (year < 30)
        year += 2000;
      else if (year < 1000)
        year += 1900;

      return year;
    }
    ...

    int result1 = ObtainYear("Jenuary 01, 2003."); // <- 2003 
    int result2 = ObtainYear("01:02:79 ."); // <- 1979