【问题标题】:How to extract name and version from string如何从字符串中提取名称和版本
【发布时间】:2019-08-22 20:01:03
【问题描述】:

我有很多文件名,例如:

libgcc1-5.2.0-r0.70413e92.rbt.xar
python3-sqlite3-3.4.3-r1.0.f25d9e76.rbt.xar
u-boot-signed-pad.bin-v2015.10+gitAUTOINC+1b6aee73e6-r0.02df1c57.rbt.xar

我需要从中可靠地提取名称、版本和“rbt”或“norbt”。什么是最好的方法?我正在尝试正则表达式,例如:

(?<fileName>.*?)-(?<version>.+).(rbt|norbt).xar

问题是文件名和版本都可以有多个分号。所以我不确定我有两个问题是否有答案:

  1. 提取此类值的最佳策略是什么?
  2. 如何确定哪个版本更高?

预期输出是:

libgcc1, 5.2.0-r0.70413e92, rbt
python3-sqlite3, 3.4.3-r1.0.f25d9e76, rbt
u-boot-signed-pad.bin, v2015.10+gitAUTOINC+1b6aee73e6-r0.02df1c57, rbt

【问题讨论】:

  • .+ 版本中,我认为您还需要一个? 以使其不贪婪
  • 这 3 个示例的预期输出是什么?
  • 第三个文件名中的“10+gitAUTOINC+”表示“版本”部分的可变性太大。为了可靠地提取想要的信息,您需要对文件名的格式进行一些保证。有吗?

标签: c# regex parsing comparison version


【解决方案1】:

测试以下代码并与正则表达式完美配合。我使用了从右到左的选项

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication107
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] inputs = {
                                  "libgcc1-5.2.0-r0.70413e92.rbt.xar",
                                  "python3-sqlite3-3.4.3-r1.0.f25d9e76.rbt.xar",
                                  "u-boot-signed-pad.bin-v2015.10+gitAUTOINC+1b6aee73e6-r0.02df1c57.rbt.xar"
                              };

            string pattern = @"(?'prefix'.+)-(?'middle'[^-][\w+\.]+-[\w+\.]+)\.(?'extension'[^\.]+).\.xar";

            foreach (string input in inputs)
            {
                Match match = Regex.Match(input, pattern, RegexOptions.RightToLeft);
                Console.WriteLine("prefix : '{0}', middle : '{1}', extension : '{2}'",
                    match.Groups["prefix"].Value,
                    match.Groups["middle"].Value,
                    match.Groups["extension"].Value
                    );
            }
            Console.ReadLine();


        }
    }


}

【讨论】:

    【解决方案2】:

    这将在不使用 Regex 的情况下为您提供所需的内容:

    var fileNames = new List<string>(){
        "libgcc1-5.2.0-r0.70413e92.rbt.xar",
        "python3-sqlite3-3.4.3-r1.0.f25d9e76.rbt.xar",
        "u-boot-signed-pad.bin-v2015.10+gitAUTOINC+1b6aee73e6-r0.02df1c57.rbt.xar"
    };
    foreach(var file in fileNames){
        var spl = file.Split('-');
        string name = string.Join("-",spl.Take(spl.Length-2));
        string versionRbt = string.Join("-",spl.Skip(spl.Length-2));
        string rbtNorbt = versionRbt.IndexOf("norbt") > 0 ? "norbt" : "rbt";
        string version = versionRbt.Replace($".{rbtNorbt}.xar","");
        Console.WriteLine($"name={name};version={version};rbt={rbtNorbt}");
    }
    

    输出:

    name=libgcc1;version=5.2.0-r0.70413e92;rbt=rbt
    name=python3-sqlite3;version=3.4.3-r1.0.f25d9e76;rbt=rbt
    name=u-boot-signed-pad.bin;version=v2015.10+gitAUTOINC+1b6aee73e6-r0.02df1c57;rbt=rbt
    

    编辑:

    或者使用正则表达式:

    var m = Regex.Match(file,@"^(?<fileName>.*)-(?<version>.+-.+)\.(rbt|norbt)\.xar$");
    string name = m.Groups["fileName"].Value;
    string version = m.Groups["version"].Value;
    string rbtNorbt = m.Groups[1].Value;
    

    输出将是相同的。两种方法都假定“版本”有一个-

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-18
      • 1970-01-01
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多