过滤字符串并从中创建新的字符串

时间:2015-09-13 00:40:09

标签: c# string winforms

我有一个日志,其中包含以下信息:

Jane opened the video file at 9/10/2015 7:30 AM

Bob opened the video file at 9/11/2015 7:38 AM

Dave opened the video file at 9/12/2015 10:30 AM

我希望将此文本文件过滤为仅当前日期和已打开video文件的用户显示,并创建一个新的字符串,如下所示:

Dave opened the video file at 9/12/2015 10:30 AM

然后,将其与用户列表进行比较,以查看今天谁没有打开该文件的用户,因此我会收到JaneBob今天尚未打开该文件的通知。

这是我尝试过的:

    private void refreshbtn_Click(object sender, EventArgs e)
    {
        string currentdate = DateTime.Now.ToShortDateString();
        string[] logfile = File.ReadAllLines(@"C:\log.txt");
        string[] users = {"Jane", "Bob", "Dave"};

        if (!logfile.Contains(currentdate))
        {
            logfile.Where(val => val != currentdate).ToArray();

            if (logfile.Contains(users.ToString()))
            {
                string x = users.ToString();
                richTextBox1.Text = x;

            }
        }
    }

是否有人能够发现我出错的地方和/或向我解释什么是正确的过程?

3 个答案:

答案 0 :(得分:2)

问题是.Contains正在数组上运行,而不是 String 。数组上的.Contains只匹配整个数组元素。

示例,logfile.Contains("Dave opened the video file at 9/12/2015 10:30 AM")为真,但logfile.Contains("Dave")为假。

您可以尝试这样的事情(未经测试):

String[] watchers = logfile.where(s => s.Contains(currentdate) && users.Any(s.Contains))).toArray();

this answer的完全道具,我不得不快速仔细检查如何在另一个数组中查找此元素的子集)

答案 1 :(得分:2)

我注意到了一些事情。

  • 此次通话logfile.Where(val => val != currentdate).ToArray()未使用此结果。 Where()基于谓词返回新序列,而不是改变现有序列。
  • logfile.Contains(currentdate)正在检查logfile中的任何字符串是否等于currentdate字符串。根据您提供的格式,不是一个安全的答案。这个Contains()调用是在日志文件数组上进行的,而不是每个字符串。您可能需要logfile.Any(line => line.Contains(currentdate)),它将检查是否有任何字符串包含currentdate字符串。这可能有点令人困惑 - 但请注意Contains()调用linestring.Contains()方法,而不是Enumerable扩展方法。

这是一个你可能适应你的程序的片段,

var currentDate = DateTime.Now.ToShortDateString();
var logFile = File.ReadAllLines(@"log.txt");
var users = new [] { "Jane", "Bob", "Dave" };

var viewers = from line in logFile
                    where line.Contains(currentDate)
                    select users.First(user => line.Contains(user));

var transgressers = users.Except(viewers);
foreach (var user in transgressers)
{
    Console.WriteLine(user);
}

如果这是一次性的情况,这可能很好,但是如果你有这个日志文件的其他用户,我建议你将这些条目解析为对象,这样你就可以制作更有意义的代码。

鉴于以下两种类型:

class User
{
    public string Name { get; }
}

class UserView
{
    public User Viewer { get; }
    public DateTime ViewTime {get; }
}

和每个的IEnumerable,你可以缩短为:

var nonViews = users.Except(
                views.Where(v => v.ViewTime.Date == DateTime.Today)
                     .Select(v => v.Viewer));

答案 2 :(得分:0)

你没告诉我们你得到了什么,但是:

  • 第7行的情况明显相反。
  • 您没有对第9行ToArray()的结果做任何事情。
  • users.ToString()完全没有意义(你期望到那里去做什么?)

我建议您打开调试器并开始逐步查看您的程序正在执行的操作。