在C#中查找包含版本号的文件名

时间:2015-08-10 16:43:06

标签: c#

我有嵌入版本号的文件名,类似于NuGet的命名方案。例子:

A.B.C.1.2.3.4.zip
A.B.C.1.2.3.5.zip
A.B.C.3.4.5.dll
A.B.C.1.2.3.6.zip
A.B.C.1.2.3.dll
X.Y.Z.7.8.9.0.zip
X.Y.Z.7.8.9.1.zip

给定“A.B.C.1.2.3”模式,如何找到匹配的所有文件和目录,无论版本号如何?我同时支持major.minor.build.revisionmajor.minor.build计划。

即,在“A.B.C.1.2.3”中,返回以下列表:

A.B.C.1.2.3.4.zip
A.B.C.1.2.3.5.zip
A.B.C.1.2.3.6.zip
A.B.C.1.2.3.dll
A.B.C.3.4.5.dll

确定哪个文件名具有最高版本的加分点。

7 个答案:

答案 0 :(得分:2)

如果您知道文件名以版本结尾,则可以Split .上的文件名字符串。然后从末尾向后迭代(跳过扩展名)并停在第一个非数字字符串上。 (TryParse可能对此有好处。)然后你可以string.Join剩下的部分,并且你有包名。

为搜索词执行此操作以查找包名称,然后查找目录中的每个文件,并且只能比较包名称。

答案 1 :(得分:2)

对jdwweng的回答以及31eee384的回答是他的想法。这个答案基本上结合了两个想法。

首先,您可以创建一个自定义类:

class CustomFile
{
    public string FileName { get; private set; }
    public Version FileVersion { get; private set; }

    public CustomFile(string file)
    {
        var split = file.Split(".".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

        int versionIndex;
        int temp;

        for (int i = split.Length - 2; i >= 0; i--)
        {
            if (!Int32.TryParse(split[i], out temp))
            {
                versionIndex = i+1;
                break;
            }
        }

        FileName = string.Join(".", split, 0, versionIndex);
        FileVersion = Version.Parse(string.Join(".", split, versionIndex, split.Length - versionIndex - 1));
    }
}

使用它来解析文件名,然后可以根据它进行过滤。

string[] input = new string[] {
    "A.B.C.D.1.2.3.4.zip",
    "A.B.C.1.2.3.5.zip",
    "A.B.C.3.4.5.dll",
    "A.B.C.1.2.3.6.zip",
    "A.B.C.1.2.3.dll",
    "X.Y.Z.7.8.9.0.zip",
    "X.Y.Z.7.8.9.1.zip"
};

var parsed = input.Select(x => new CustomFile(x));
var results = parsed
    .Where(cf => cf.FileName == "A.B.C")
    .OrderByDescending(cf=>cf.FileVersion)
    .ToList();

在此示例中,第一个元素的版本最高。

答案 2 :(得分:1)

试试这个

base.py

答案 3 :(得分:0)

尝试使用正则表达式,如下面的示例

    var firstPart = Console.ReadLine();

    var names = new List<string>
    {
        "A.B.C.1.2.3.4.zip",
        "A.B.C.1.2.3.5.zip",
        "A.B.C.1.2.3.6.zip",
        "A.B.C.1.2.3.dll",
        "X.Y.Z.7.8.9.0.zip",
        "X.Y.Z.7.8.9.1.zip"
    };

    var versionRegexp = new Regex("^" + firstPart + "\\.([\\d]+\\.){1}([\\d]+\\.){1}([\\d]+\\.){1}([\\d]+\\.)?[\\w\\d]+$");

    foreach (var name in names)
    {
        if (versionRegexp.IsMatch(name))
        {
            Console.WriteLine(name);
            foreach (Group group in versionRegexp.Match(name).Groups)
            {
                Console.WriteLine("Index {0}: {1}", group.Index, group.Value);
            }
        }
    }

    Console.ReadKey();

答案 4 :(得分:0)

这仅使用LINQ,假设文件名本身不以数字结尾:

List<string> names = new List<string> { "A.B.C.1.2.3.4.zip",
                                        "A.B.C.1.2.3.5.zip",
                                        "A.B.C.3.4.5.dll",
                                        "A.B.C.1.2.3.6.zip" ,
                                        "A.B.C.1.2.3.dll",
                                        "X.Y.Z.7.8.9.0.zip",
                                        "X.Y.Z.7.8.9.1.zip" };

var groupedFileNames = names.GroupBy(file => new string(Path.GetFileNameWithoutExtension(file)
                                                         .Reverse()
                                                         .SkipWhile(c => Char.IsDigit(c) || c == '.')
                                                         .Reverse().ToArray()));

foreach (var g in groupedFileNames)
{
    Console.WriteLine(g.Key);
    foreach (var file in g)
        Console.WriteLine("    " + file);
}

答案 5 :(得分:0)

您可以使用新版本()来比较这样的版本:

List<string> fileNames = new List<string>();
            fileNnames.AddRange(new[] {
                "A.B.C.1.2.3.4.zip",
                "A.B.C.1.2.3.5.zip",
                "A.B.C.3.4.5.dll",
                "A.B.C.1.2.3.6.zip",
                "A.B.C.1.2.3.dll",
                "X.Y.Z.7.8.9.0.zip",
                "X.Y.Z.7.8.9.1.zip" });

            string filter = "a.b.c";

            var files = fileNames
                //Filter the filenames that start with your filter
                .Where(f => f
                      .StartsWith(filter, StringComparison.InvariantCultureIgnoreCase)
                      )
               //retrieve the version number and create a new version element to order by
                .OrderBy(f =>
                    new Version( 
                        f.Substring(filter.Length + 1, f.Length - filter.Length - 5)
                        )
                );

Results

答案 6 :(得分:0)

首先,我认为您可以使用Version类进行比较。 我相信下面的功能可以让你从某个名称开始的版本。 它匹配起始名称,然后执行非贪婪搜索,直到点和数字后跟2或3点数字对和后面的任何字符。

public static List<Version> GetLibraryVersions(List<string> files, string Name)
{
    string regexPattern = String.Format(@"\A{0}(?:.*?)(?:\.)(\d+(?:\.\d+){{2,3}})(?:\.)(?:.*)\Z", Regex.Escape(Name));
    Regex regex = new Regex(regexPattern);
    return files.Where(f => regex.Match(f).Success).
            Select(f => new Version(regex.Match(f).Groups[1].Value)).ToList();
}