我有嵌入版本号的文件名,类似于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.revision
和major.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
确定哪个文件名具有最高版本的加分点。
答案 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)
)
);
答案 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();
}