我如何使用LINQ和字符串解析完成此示例?
我正在尝试编写一个简单的程序来比较单独文件夹中的文件。 我目前正在使用LINQ to Objects来解析文件夹,并希望在我的结果集中包含从字符串中提取的信息。
这是我到目前为止所拥有的:
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查询,以便:
我相信查询的基本布局如下所示,但我不确定如何最好地完成它(我有一些关于如何做到这一点的想法,但我有兴趣听到其他人如何可能会这样做):
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(@"^.*(?_w_Drive(?d+)(?_i(?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. (?...) 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". (?d+) At least one digit, saved as ImageNumber. (?...)? An optional increment description.
增量是:
_i A literal underscore, then the letter i. (?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(@"^.*(?_w_Drive(?d+)(?_i(?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:tempbackup 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; } }
请注意,对于正则表达式,我假设文件名中有一些一致性,如果它们偏离了您提到的格式,那么您将不得不调整它们。
上述就是C#学习教程:我如何使用LINQ和字符串解析完成此示例?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1000497.html