C# 逐行分析并存储是否符合标准,否则忽略

C# 逐行分析并存储是否符合标准,否则忽略,c#,filter,streamreader,C#,Filter,Streamreader,我已经在这件事上翻了很多遍,但没有找到我要找的东西 输入:多行(数百行,偶尔数千行)ASCII文本,长度从97个字符到500多个字符不等。我是否要保留此数据的标准仅包含在前3个字符中(始终是数字-我感兴趣的是任意值100200和300) 所需的输出只有那些以100、200或300开头的,其余的我可以忽略 这是我的streamreader,它当前输出到控制台: using System; using System.Collections.Generic; using System.IO; cla

我已经在这件事上翻了很多遍,但没有找到我要找的东西

输入:多行(数百行,偶尔数千行)ASCII文本,长度从97个字符到500多个字符不等。我是否要保留此数据的标准仅包含在前3个字符中(始终是数字-我感兴趣的是任意值100200和300)

所需的输出只有那些以100、200或300开头的,其余的我可以忽略

这是我的streamreader,它当前输出到控制台:

using System;
using System.Collections.Generic;
using System.IO;

class Program
{
public void Do
{

    // Read in a file line-by-line, and store in a List.

    List<string> list = new List<string>();
    using (StreamReader reader = new StreamReader("File.dat"))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            list.Add(line); // Add to list.
            Console.WriteLine(line); // Write to console.
        //    Console.ReadLine();
        }
    }
}
}
但我不确定如何定义第一个3Char类。这是对原始数据进行的唯一筛选


之后,我将根据其中包含的其他标准分析此过滤数据集,但在请求任何帮助之前,我将自己尝试一下。

是否有理由不将此条件添加到循环中

while ((line = reader.ReadLine()) != null)
{
    var beginning = line.Substring(0, 3);
    if(beginning != "100" && beginning != "200" && beginning != "300")
        continue;
    list.Add(line); // Add to list.
    Console.WriteLine(line); // Write to console.
}
在最简单的层面上:

if(line.StartsWith("100") || line.StartsWith("200") || line.StartsWith("300"))
{
    list.Add(line); // Add to list.
    Console.WriteLine(line); // Write to console.
}
如果文件很大(例如,数十万行),那么也值得考虑将其实现为迭代器块。但是“开始”测试非常简单

如果你需要更多的灵活性,我会考虑正则表达式;例如:

static readonly Regex re = new Regex("^[012]00", RegexOptions.Compiled);

...
while (...)
{
    if(re.IsMatch(line))
    {
        list.Add(line); // Add to list.
        Console.WriteLine(line); // Write to console.
    }
}

此代码更具可读性,可满足您的需要:

var allowedNumbers = new[]{ "100", "200", "300" };
IEnumerable<String> lines = File
                   .ReadLines("File.dat")
                   .Where(l => allowedNumbers.Any(num => l.StartsWith(num)));
由于您想将这些行添加到
列表中
,因此可以使用
可枚举.ToList
而不是
foreach

foreach(string line in lines)
{
    Console.WriteLine(line); // Write to console.
}
List<string> list = lines.ToList();
List=lines.ToList();

也可以考虑在输出中填充一个StrugBu建器,如果不需要实际输出的话。time@trippino我们不知道OP使用列表的目的是什么;我认为stringbuilder在这里不适用。控制台在我看来就像一个UI跟踪器-保持“原样”可能没问题是的,这只是一个快速调试的提示下一步是每100行开始,找到位置40-45中的数字,并按字符位置20-23中的变量小计,每行200(并按24-26中的变量小计至50-55,300、27-29中的变量小计至60-65等。最终输出将这些总计分为20-23等中的相应类别。)每100、200和300个起始数字。很好的解决方案,但可能存在瓶颈。@PLB:您在哪里看到瓶颈?请注意,在返回结果之前,不会将整个文件读入内存。有关详细信息,请参阅其文档的“备注”部分。@DanielHilgarth
Where
将迭代读取行,而
any
>将迭代
allowedMembers
。而这可以在on循环中完成。我并不是说这是一个糟糕的解决方案。请不要误解我的意思。:@PLB:您如何在一个循环中完成此操作?@PLB:我假设您没有延迟执行的点。将
Where
理解为循环中的
if
-子句,而不是附加循环<代码>上述使用的任何
方法与Marc Gravells的方法相同。
List<string> list = lines.ToList();