新来的C#学习者。我已经浏览了很多已经在这里发布的问题,如果我错过了这样一个已经被问到的问题,我很抱歉。
背景
我使用的程序生成Excel文件,这些文件的名称包含创建它们的日期。生成了数千个需要排序的Excel文件。我在这里的任务是从这些文件名中提取信息,这样我就可以在确认后将文件移动到适当的位置。我正在使用一个程序,它可以成功地找到具有特定字符串的所有相关文件。我已将这些文件的名称存储在数组中。
示例文件名: IMPORTANT_NAME_LISTED (文本)xx-xxx.xlsx
所知
日期以月/日/年格式存储,并且100 %一致(意味着每个文件将产生相同的格式、大小和日期位置)。
我一直在努力开发一种针对目标的解决方案。之前的文件扩展名和提取日期,但我正在挣扎。
我的策略
我有一个初始决定,确保存储了所有文件名的数组包含值。
//code that extracts file names exists above
//file names which interest me are stored within "fileNameArray"
//Determine if the array that collected file names contains values
if (fileNameArray.Length > 1)
{
for (int k = 0; k <= fileNameArray.Length; k++)
{
//Extract date from "[xx-xx-xx] [HH-MM]"
//Transform MM/DD/YY to YY/MM/DD and temporarily store
//Compare each date value that exist within the string
//Target the most recent file - find the array index
//(Ex: 20180831 - today's date)
}
}我的问题源于在保留数组索引的同时正确地解析这些单独的数组项。
你们中有谁推荐使用的方法吗?林克?Array.FindAll功能?
我非常感谢你的帮助。
-Chris
编辑:进一步了解我的情况.
我有一个Excel文件目录,它可以超过1-3k文件。我有一个程序,它读取所有Excel文件的文件名。大量的过滤/排序发生在我想要实现的代码之前。
我一直在努力解决有关处理同名文件的问题。例如:
我有4个文件包含相同的部分名称"DILITHIUM_CRYSTYAL_FUEL_TIME"
我的程序必须能够通过核心名称"DILITHIUM_CRYSTYAL_FUEL_TIME"过滤/搜索文件名。如果我有多个具有相同名称的文件,我需要能够以一种隔离文件名内时间戳并找到最近的文件的方式解析文件名。
我的文件将始终以100%一致的方式显示文件扩展名左侧的时间戳。
我需要能够提取这个时间戳,并与其他文件进行比较,并分离出最最新的文件。
发布于 2018-08-31 21:26:26
我还会选择regex、字符串解析和linq:
这里的工作示例:https://dotnetfiddle.net/veUq2N
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class Program
{
private static Random random = new Random();
private static Regex fileNameFragmentPattern = new Regex(@"\[(.*?)\]\.xlsx");
private const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
public static void Main()
{
var fileNames = new List<string>();
// Generate random file names
for (var i = 0; i < 10000; i++) {
fileNames.Add(RandomString(random.Next(8,10)) + "_" + RandomString(random.Next(4,5)) + "_" + "(TEXT) [" + RandomDate().ToString("MM-dd-yyyy") + "].xlsx");
}
// sort files by parsed dates
var dateSortedFileNames = fileNames.OrderByDescending( f => ExtractDate(f));
foreach (var fileName in dateSortedFileNames) {
// you can do anything with sorted files here (or anywhere else below :)
Console.WriteLine(fileName);
}
}
public static DateTime ExtractDate(string fileName) {
var fragment = fileNameFragmentPattern.Match(fileName).Value;
var month = int.Parse(fragment.Substring(1,2));
var day = int.Parse(fragment.Substring(4,2));
var year = int.Parse(fragment.Substring(7,4));
return new DateTime(year, month, day);
}
public static string RandomString(int length)
{
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
public static DateTime RandomDate(int min = -9999, int max = 9999)
{
return DateTime.Now.AddDays(random.Next(min,max));
}
}发布于 2018-08-31 20:38:04
LINQ是一个很好的选择,结合Regex进行解析。
var dateRE = new Regex(@"\[(\d\d-\d\d-\d\d)\] \[(\d\d-\d\d)\](?=.xlsx)", RegexOptions.Compiled);
if (fileNameArray.Length > 0) {
var ans = fileNameArray.Select((n, i) => {
var dtMatch = dateRE.Match(n);
return new { Filename = n, Index = i, Filedate = DateTime.ParseExact(dtMatch.Groups[1].Value+" "+dtMatch.Groups[2].Value, "MM-dd-yy HH-mm", CultureInfo.InvariantCulture) };
})
.OrderByDescending(nid => nid.Filedate)
.First();
}如果要以不同的方式处理文件名,可以使用其他LINQ操作替换First()。
发布于 2018-08-31 22:04:47
这是一个非正则表达式。
var files = new List<string>
{
"IMPORTANT_NAME_LISTED (TEXT) [05-26-92].xlsx",
"IMPORTANT_NAME_LISTED (TEXT) [11-02-89].xlsx",
"IMPORTANT_NAME_LISTED (TEXT) [02-21-96].xlsx"
};
foreach (var fileName in files)
{
var nameOnly = Path.GetFileNameWithoutExtension(fileName);
var dateStr = nameOnly.Substring(nameOnly.Length - 9, 8);
if (DateTime.TryParseExact(dateStr, "MM-dd-yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
Console.WriteLine(date.ToShortDateString());
}因为你提到文件名的“日期”部分是100%一致的,而且我们知道你的“日期”的长度将永远是8。
nameOnly.Substring(nameOnly.Length - 9, 8);将提取开始于第一个[之后的字符串,并提取在]之前结束的8字符。
如果您100%肯定文件扩展名始终是.xlsx,那么您可以更短一些代码。
foreach (var fileName in files)
{
var dateStr = fileName.Substring(fileName.Length - 14, 8);
if (DateTime.TryParseExact(dateStr, "MM-dd-yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
Console.WriteLine(date.ToShortDateString());
}https://stackoverflow.com/questions/52122202
复制相似问题