Я пытаюсь записать простую программу, которая сравнит файлы в отдельных папках. Я в настоящее время использую LINQ для Объектов проанализировать папку и хотел бы к включенной информации, извлеченной из строки в моем наборе результатов также.
Вот то, что я имею до сих пор:
FileInfo[] fileList = new DirectoryInfo(@"G:\Norton Backups").GetFiles();
var results = from file in fileList
orderby file.CreationTime
select new { file.Name, file.CreationTime, file.Length };
foreach (var x in results)
Console.WriteLine(x.Name);
Это производит:
AWS025.sv2i
AWS025_C_Drive038.v2i
AWS025_C_Drive038_i001.iv2i
AWS025_C_Drive038_i002.iv2i
AWS025_C_Drive038_i003.iv2i
AWS025_C_Drive038_i004.iv2i
AWS025_C_Drive038_i005.iv2i
...
Я хотел бы изменить запрос LINQ так, чтобы:
_C_Drive038
в примерах выше, хотя 038
и возможно буква диска могла измениться)._i0XX
в конце имени файла).038
).001
было бы инкрементное число),Я полагаю, что базовый макет запроса был бы похож на следующее, но я не уверен, как лучше всего завершить его (я получил некоторое представление для того, как часть этого могла бы быть сделана, но мне интересно к услышанному, как другие могли бы сделать это):
var results = from file in fileList
let IsMainBackup = \\ ??
let ImageNumber = \\ ??
let IncrementNumber = \\ ??
where \\ it is a backup file.
orderby file.CreationTime
select new { file.Name, file.CreationTime, file.Length,
IsMainBackup, ImageNumber, IncrementNumber };
При поиске ImageNumber
и IncrementNumber
, Я хотел бы предположить, что местоположение этих данных не всегда фиксируется, значение, я хотел бы знать о хорошем способе проанализировать это (Если это требует RegEx, объясните, как я мог бы использовать его).
Примечание: Большая часть моего прошлого опыта в парсинге текста, включенного с помощью основанных на местоположении строковых функций, такой как LEFT
, RIGHT
, или MID
. Я не возвратился бы к ним, если существует лучший путь.
Использование регулярных выражений:
Regex regex = new Regex(@"^.*(?<Backup>_\w_Drive(?<ImageNumber>\d+)(?<Increment>_i(?<IncrementNumber>\d+))?)\.[^.]+$");
var results = from file in fileList
let match = regex.Match(file.Name)
let IsMainBackup = !match.Groups["Increment"].Success
let ImageNumber = match.Groups["ImageNumber"].Value
let IncrementNumber = match.Groups["IncrementNumber"].Value
where match.Groups["Backup"].Success
orderby file.CreationTime
select new { file.Name, file.CreationTime, file.Length,
IsMainBackup, ImageNumber, IncrementNumber };
Вот описание регулярного выражения:
^ Start of string.
.* Allow anything at the start.
(?<Backup>...) Match a backup description (explained below).
\. Match a literal period.
[^.]+$ Match the extension (anything except periods).
$ End of string.
Резервное копирование:
_\w_Drive A literal underscore, any letter, another underscore, then the string "Drive".
(?<ImageNumber>\d+) At least one digit, saved as ImageNumber.
(?<Increment>...)? An optional increment description.
Приращение:
_i A literal underscore, then the letter i.
(?<IncrementNumber>\d+) At least one digit, saved as IncrementNumber.
Вот тестовый код, который я использовал:
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Linq;
class Program
{
static void Main(string[] args)
{
FileInfo[] fileList = new FileInfo[] {
new FileInfo("AWS025.sv2i"),
new FileInfo("AWS025_C_Drive038.v2i"),
new FileInfo("AWS025_C_Drive038_i001.iv2i"),
new FileInfo("AWS025_C_Drive038_i002.iv2i"),
new FileInfo("AWS025_C_Drive038_i003.iv2i"),
new FileInfo("AWS025_C_Drive038_i004.iv2i"),
new FileInfo("AWS025_C_Drive038_i005.iv2i")
};
Regex regex = new Regex(@"^.*(?<Backup>_\w_Drive(?<ImageNumber>\d+)(?<Increment>_i(?<IncrementNumber>\d+))?)\.[^.]+$");
var results = from file in fileList
let match = regex.Match(file.Name)
let IsMainBackup = !match.Groups["Increment"].Success
let ImageNumber = match.Groups["ImageNumber"].Value
let IncrementNumber = match.Groups["IncrementNumber"].Value
where match.Groups["Backup"].Success
orderby file.CreationTime
select new { file.Name, file.CreationTime,
IsMainBackup, ImageNumber, IncrementNumber };
foreach (var x in results)
{
Console.WriteLine("Name: {0}, Main: {1}, Image: {2}, Increment: {3}",
x.Name, x.IsMainBackup, x.ImageNumber, x.IncrementNumber);
}
}
}
И вот результат, который я получаю:
Name: AWS025_C_Drive038.v2i, Main: True, Image: 038, Increment:
Name: AWS025_C_Drive038_i001.iv2i, Main: False, Image: 038, Increment: 001
Name: AWS025_C_Drive038_i002.iv2i, Main: False, Image: 038, Increment: 002
Name: AWS025_C_Drive038_i003.iv2i, Main: False, Image: 038, Increment: 003
Name: AWS025_C_Drive038_i004.iv2i, Main: False, Image: 038, Increment: 004
Name: AWS025_C_Drive038_i005.iv2i, Main: False, Image: 038, Increment: 005
Было немного весело разработать хороший ответ на этот вопрос :)
Приведенный ниже фрагмент кода дает вам то, что вам нужно. Обратите внимание на использование шаблона поиска при извлечении файлов - нет смысла извлекать больше файлов, чем необходимо. Также обратите внимание на использование функции parseNumber (), это было просто, чтобы показать вам, как изменить результат строки из регулярного выражения на число, если оно вам понадобится в этом формате.
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new Form1());
GetBackupFiles(@"c:\temp\backup files");
}
static void GetBackupFiles(string path)
{
FileInfo[] fileList = new DirectoryInfo(path).GetFiles("*_Drive*.*v2i");
var results = from file in fileList
orderby file.CreationTime
select new
{ file.Name
,file.CreationTime
,file.Length
,IsMainBackup = file.Extension.ToLower() == ".v2i"
,ImageNumber = Regex.Match(file.Name, @"drive([\d]{0,5})", RegexOptions.IgnoreCase).Groups[1]
,IncrementNumber = parseNumber( Regex.Match(file.Name, @"_i([\d]{0,5})\.iv2i", RegexOptions.IgnoreCase).Groups[1])
};
foreach (var x in results)
Console.WriteLine(x.Name);
}
static int? parseNumber(object num)
{
int temp;
if (num != null && int.TryParse(num.ToString(), out temp))
return temp;
return null;
}
}
Обратите внимание, что с регулярными выражениями я предполагаю некоторую согласованность в именах файлов, если они будут отличаться от указанного вами формата, вам придется их скорректировать.