【问题标题】:Trying to ignore blank lines to parse the last occurrence of a string in a text file试图忽略空行以解析文本文件中最后一次出现的字符串
【发布时间】:2020-06-14 06:54:16
【问题描述】:

所以我的文本文件结构如下:

Date: 12/23/23
.
.
.
Date: 12/23/66
.
.
Date: 12/25/67

为此,我试图获取日期的最后一次发生,即:

Date: 12/25/67

有了这个,我已经知道如何通过这段代码:

string date = "";
foreach(string line in File.ReadAllLines("mytext.txt"))
{
    date = GetDate_value(line, date);    
}

public static string GetDate_value(string line, string date)
{ 
    if (line.Contains("Date:"))
    {
        date = line;   
    }

    string[] separatingStrings = { "Date: " };
    string[] str = date.Split(separatingStrings, System.StringSplitOptions.RemoveEmptyEntries);
    Console.WriteLine("[{0}]", string.Join(", ", str));
    return str.Last();
}

有了这个,当我返回日期时,我得到了最后一次出现。但是,我试图将其进一步解析到仅包含 12/25/67 的位置。

有了这个,我知道上面的逻辑是怎么回事。但是,当我尝试解析文件时,我得到一个错误,说元素中的数组不存在。进一步检查显示与我的Console.WriteLine的数组显示:

[]
[]
[]
[]
[  , 12/25/67]
[  , 12/25/67]
[  , 12/25/67]
[  , 12/25/67]
.
.(repeats for how many lines in text file)

我想知道为什么我在开头部分没有任何元素,而一切都应该是:

[  , 12/25/67]
[  , 12/25/67]
[  , 12/25/67]
[  , 12/25/67]

我尝试使用它来替换 foreach 行:

foreach (string line in File.ReadAllLines(file).Where(line => !string.IsNullOrWhiteSpace(line)))

但是它仍然没有忽略最后一行。我将如何使它在开始时忽略 null 元素?

编辑

所以在获取日期函数中使用这个 if 语句:

string[] separatingStrings = { "Date: " };
string[] str = date.Split(separatingStrings, System.StringSplitOptions.RemoveEmptyEntries);
if(str.Length == 0)
{

    Console.WriteLine("null");

}

我发现这些values([]) 的长度为 0,那么我怎么能跳过长度为 0 的数组来忽略它?

【问题讨论】:

  • 如果你知道格式,你可以简单地使用 C# 的 Remove 方法,一旦你得到该行
  • 您能进一步解释一下吗?
  • 你得到 Date: 12/25/67 所以你可以删除 Date: 从字符串中
  • 这可以帮助你string str = File.ReadLines("test.txt").Where(s => s.Contains("Date:")).ToList().Last().Remove(6);。你必须处理null 案件
  • 你不是已经问过类似的question了吗?

标签: c# arrays string parsing


【解决方案1】:

也许尝试这样做:

string last =
    File
        .ReadLines("mytext.txt")
        .Aggregate(
            (string)null,
            (a, x) =>
                x.StartsWith("Date: ")
                    ? x.Substring("Date: ".Length) 
                    : a)

如果lastnull,那么您的文本文件不包含以"Date: " 开头的行,否则它将包含文件中的最后一个日期(尽管仍然是一个字符串)。

我也选择了File.ReadLines,因为它会懒惰地读取文件,所以文件大小应该不是问题。

【讨论】:

  • 对不起,我真的不明白,我会在我的 foreach 循环中传递这个吗?
  • @thesenate42069 不,该代码将替换您的 foreach 循环。最后你会找到你想要的结果。这就是为什么他说:这样做而不是
  • @thesenate42069 - 是的,如果我不够清楚,抱歉。这段代码就是你所需要的。
【解决方案2】:

您的代码 sn-p 中的问题是 GetDate_value 函数,无论传递的行是否包含 Date:,您都在其中执行相同的代码。您需要将所有内容移至 if 块以返回日期,否则该函数应返回 nullstring.Empty

void TheCaller()
{
    var f = "myText.txt";
    var dates = new List<string>();

    foreach (string line in File.ReadLines(f)
        .Where(l => l.Length > 6)) //At least...
    {
        var date = GetDate_value(line);

        if (date != null)
            dates.Add(date);
    }

    Console.WriteLine("[{0}]", string.Join(", ", dates));
}

public static string GetDate_value(string line)
{
    string output = null;

    if (line.StartsWith("Date:"))
    {
        output = line.Split(new[] { " " }, 
            StringSplitOptions.RemoveEmptyEntries).LastOrDefault();

    }
    return output;
}

您可以将上面的内容替换为:

void TheCaller()
{
    var f = "myText.txt";
    var dates = File.ReadLines(f)
        .Where(l => l.StartsWith("Date: "))
        .Select(l => l.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)
        .LastOrDefault()).ToList();

    Console.WriteLine("[{0}]", string.Join(", ", dates));
}

给定示例的输出是:

[12/23/23, 12/23/66, 12/25/67]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-13
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    相关资源
    最近更新 更多