【问题标题】:Extract version number提取版本号
【发布时间】:2018-03-24 15:07:57
【问题描述】:

我试图从 HML 链接中获取版本号。

以这个为例

firefox-10.0.2.bundle

我已经把- 之后的所有东西都用

string versionNum = name.Split('-').Last();
versionNum = Regex.Replace(versionNum, "[^0-9.]", "");

它给你一个输出

10.0.2

但是,如果链接是这样的

firefox-10.0.2.source.tar.bz2

输出看起来像

10.0.2...2

我怎样才能让它在第三个 . 之后砍掉所有东西?或者我可以做到这一点,以便在检测到第一个字母时将其删除以及随后的所有内容?

【问题讨论】:

  • 您可以在一个正则表达式中完成所有操作,使用捕获组(...) 提取/捕获您想要的数字。在线正则表达式服务(例如debuggex.comregex101.comregexstorm.net/tester)可以帮助您针对任何测试字符串构建和测试您的正则表达式(这比 C# 代码中的反复试验更好、更容易)
  • 使用 Match 方法,而不是 Replace 方法。
  • 可能性 a) 使用带有偏移量的 substring()。可能性 b) 将结果字符串再次拆分为 '.'只取你需要的东西。
  • @sublimeaces 我强烈建议您查看我的答案,以更好地了解更高级和更强大的正则表达式,如果不接受它作为更好的答案:)

标签: c# regex substring


【解决方案1】:

您可以通过单个正则表达式匹配来解决此问题。 这是一个例子:

using System;
using System.Text.RegularExpressions;

public class Program
{
    public static void Main()
    {
        Regex regex = new Regex(@"\d+.\d+.\d+");
        Match match = regex.Match("firefox-10.0.2.source.tar.bz2");
        if (match.Success)
        {
            Console.WriteLine(match.Value);
        }
    }
}

【讨论】:

    【解决方案2】:

    将“firefox-10.0.2.source.tar.bz2”拆分为“10.0.2.source.tar.bz2”后

    string a = "10.0.2.source.tar.bz2";
    string[] list = a.Split(new char [] { '.' });
    string output = ""
    foreach(var item in list)
    {
        if item is integer then // try to write this part
            output += item + ".";
    
    
    }
    after that remove the last character from output.
    

    【讨论】:

      【解决方案3】:

      虽然晚了,但我觉得这个答案会更贴切:

      Regex r = new Regex(@"[\d\.]+(?![a-zA-Z\-])");
      Match m = r.Match(name);
      
      Console.WriteLine(m.Value);
      

      改进 -

      虽然@Samuel 的答案有效,但如果构建是10.2.2.3 会发生什么?他的正则表达式会给出10.2.2 - 部分答案,因此是错误的。

      使用我发布的正则表达式,匹配就完成了。

      解释-

      [\d\.]+ 匹配所有数字和点的组合,例如10.2.2.34.56.78,如果构建为10.bundle,甚至只匹配10

      (?![a-zA-Z\-]) 是一个负前瞻,可确保匹配项后面没有任何字母或破折号。

      健壮性对于任何代码都绝对至关重要,因此我发布的答案在任何情况下都应该可以正常工作(因为链接可以是任何东西)。

      【讨论】:

      • 注意:输入“1..1”或“1.1.-”会发生什么?
      • @JohnLBevan 1.1.- 仍然可以使用这个正则表达式。
      • @JohnLBevan 另外,1..1 是什么意思?
      • @CoffehouseCoder,我提供的字符串是不是版本号的字符串示例,但仍会与您的正则表达式版本匹配。
      【解决方案4】:

      这是一个可以处理输入字符串中的1-4个数字(不仅仅是数字)的版本,并返回一个版本号:

      public static Version ExtractVersionNumber(string input)
      {
          Match match = Regex.Match(input, @"(\d+\.){0,3}\d+");
          if (match.Success)
          {
              return new Version(match.Value);
          }
          return null;
      }
      
      void Main()
      {
          Console.WriteLine(ExtractVersionNumber("firefox-10.source.tar.bz2"));
          Console.WriteLine(ExtractVersionNumber("firefox-10.0.source.tar.bz2"));
          Console.WriteLine(ExtractVersionNumber("firefox-10.0.2.source.tar.bz2"));
          Console.WriteLine(ExtractVersionNumber("firefox-10.0.2.5.source.tar.bz2"));
          Console.WriteLine(ExtractVersionNumber("firefox-10.0.2.5.6.source.tar.bz2"));
          Console.WriteLine(ExtractVersionNumber("firefox-10.source.tar.bz2"));
          Console.WriteLine(ExtractVersionNumber("firefox-10.0source.tar.bz2"));
          Console.WriteLine(ExtractVersionNumber("firefox-10.0.2source.tar.bz2"));
          Console.WriteLine(ExtractVersionNumber("firefox-10.0.2.5source.tar.bz2"));
          Console.WriteLine(ExtractVersionNumber("firefox-10.0.2.5.6source.tar.bz2"));
      }   
      

      说明

      基本上有两部分:

      1. (\d+\.){0,3} - 匹配一个数字(1 个或多个数字的不间断序列),紧跟一个点。匹配 0 到 3 次。
      2. \d+ - 匹配一个数字(1 个或多个数字的序列)。

      这些工作如下:

      • 当只有 1 个数字时(或者即使只有 1 个数字后跟一个点),第一部分将不匹配,第二部分将匹配数字
      • 当有 2 个数字以点分隔时,第一部分匹配第一个数字,点匹配第二个数字。
      • 对于以点分隔的 3 个数字,第一部分获取前 2 个数字和点,最后一个获取第三个数字
      • 对于以点分隔的4个或更多数字,第一部分获取前3个数字和点,第二部分获取第四个数字。任何后续的数字和点都将被忽略。

      ps。如果你想确保你只得到连字符后的数字(例如,为了避免在给定字符串firefox4.0.1-10.0.2.source.tar.bz2" 的情况下得到4.0.1),你可以在后面添加一个否定的样子,说“版本号之前的字符必须是连字符":(?<=-)(\d+\.){0,3}\d+.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-16
        • 2013-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多