【问题标题】:Is there a way to get a string up until a year value?有没有办法得到一个字符串直到一年的值?
【发布时间】:2012-01-23 01:45:14
【问题描述】:

基本上我有一些文件名,中间有一年。我只对获取年份值之前的任何字母或数字感兴趣,但只有字母和数字,而不是逗号、点、下划线等。这可能吗?也许使用正则表达式?

例如:

"A-Good-Life-2010-For-Archive"
"Any.Chararacter_Can+Come.Before!2011-RedundantInfo"
"WhatyouseeIsWhatUget.2012-Not"
"400-Gestures.In1.2000-Communication"

我想要的地方:

"AGoodLife"
"AnyChararacterCanComeBefore"
"WhatyouseeIsWhatUget"
"400GesturesIn1"

我所说的数字是指任何看起来不像年份的数字,即 1 位、2 位、3 位、5 位等等。我只想将 4 位数字识别为年份。

【问题讨论】:

    标签: c# .net regex string parsing


    【解决方案1】:

    您必须分两部分执行此操作 - 首先删除您不想要的符号,然后获取今年的所有内容(反之亦然)。

    要抓住今年的所有东西,您可以使用:

    Match match = Regex.Match(movieTitle,@"(.*)(?<!\d)(?:19|20)[0-9]{2}(?!\d)");
    // if match.Success, result is in match.Groups[1].value
    

    我制作了年份正则表达式,因此它只匹配 1900 年代或 2000 年代的事物,以确保您不会将四位数字匹配为年份,如果它们不是年份(例如“Ali-Baba-And -the-1234-Thieves.2011")。

    但是,如果您的电影标题涉及一年,那么这将不起作用(“2001:-Space-Odyssey(1968)”)。

    若要替换所有非字符,您可以将"[^a-zA-Z0-9]" 替换为""。 (我允许使用数字,因为电影的标题中可能有合法的数字)。

    已更新来自以下 cmets:

    • 如果您从末尾开始查找年份,您可能会做得更好。即找到最近出现的候选年份作为年份。因此,我在正则表达式中将.*? 更改为.*,以使标题尽可能贪婪,并且仅使用最后一年的候选人作为年份。
    • 在年底正则表达式中添加了(?!\d),在开头添加了(?&lt;!\d),这样它就不会匹配“My-title-1”而不是“My-title-120012-fdsa”和“ 2001”在“My-title-120012-fdsa”中(我没有添加边界\b,因为标题可能是“A-Good-Life2010”,全年没有边界)。
    • 将字符串更改为原始字符串 (@"..."),因此我无需担心由于 C# 解释反斜杠而在正则表达式中转义反斜杠。

    【讨论】:

    • 最好从年底开始搜索以找到年份
    • 将 "(?!\d)" 添加到模式的末尾会阻止匹配 5+-digit 序列。照原样,“Title-2012345-2011-X”将匹配“Title-”而不是“Title-20123-”。
    【解决方案2】:

    你可以这样试试

    /\b\d{4}\b/
    

    d{4}\b 将匹配单词边界处的四个 d。根据输入数据,您可能还需要考虑在开头添加另一个单词边界 (\b)。

    【讨论】:

    • 您总是希望在开头有一个单词边界,否则该模式将匹配超过 4 位的数字的最后 4 位。
    【解决方案3】:
    using System.Text.RegularExpressions;
    
    
    string GoodParts(string input) {
      Regex re = new Regex(@"^(.*\D)\d{4}(\D|$)");
      var match = re.Match(input);
      string result = Regex.Replace(match.Groups[1].Value, "[^0-9a-zA-Z]+", "");
      return result;
    }
    

    【讨论】:

      【解决方案4】:

      您可以使用Regex.Split() 使代码更加简洁(由于更简单的正则表达式可能更快):

      var str = "400-Gestures.In1.2000-Communication";
      
      var re = new Regex(@"(^|\D)\d{4}(\D|$)");
      var start = re.Split(str)[0];
      
      // remove nonalphanumerics
      var result = new string(start.Where(c=>Char.IsLetterOrDigit(c)).ToArray());
      

      【讨论】:

        【解决方案5】:

        我想你想要一个花哨的正则表达式?

        为什么不是一个简单的 for 循环?

        digitCount = 0;
        for i = 0 to strlen(filename)
        {
          if isdigit(fielname[i])
          {
             digitCount++;
             if digitCount == 4
                thePartOfTheFileNameThatYouWant = strcpy(filename, 0, i-4)
          }
          else digitCount = 0;     
        }
        

        // 对不起,我不知道升C

        【讨论】:

        • 您仍然可以在代码示例中使用实际的编程语言。
        • 算法返回超过 4 个连续数字的错误结果,例如 abcd-12345d-2000-4(将在 1234 处停止),并且不会删除非字母数字字符。
        猜你喜欢
        • 2013-06-18
        • 2022-01-24
        • 1970-01-01
        • 1970-01-01
        • 2021-07-09
        • 1970-01-01
        • 2013-07-05
        • 2021-03-29
        • 1970-01-01
        相关资源
        最近更新 更多