需要从文本文件C#中获取特定的文本行

时间:2013-10-22 23:12:18

标签: c# parsing text-files

我有一个看起来像这样的文本文件:

DeltaV User List - 17 Jun 2013
SUPPLY_CHAIN


UserID              Full Name
BAINC               C M B
BEEMANH             H B
CERIOJI             J M C
LADUCK              K L
MAYC                C M
NEWTONC             C N

DeltaV User List - 17 Jun 2013
FERM_OPER


UserID              Full Name
POULIOTM            M P
TURNERM7            M T

我需要在C#中获取每个部分的个人用户,我不知道该怎么做。我正在使用StreamReader类,它用于获取区域名称(所有大写字母),但我似乎无法获得所有用户。我有一个用户类,有2个字符串Name&区域,我正在尝试列出用户对象。

这是我到目前为止所尝试的:(我已经在代码中声明了一个User对象列表)

        // read user list text file
        var userReader = new StreamReader(File.OpenRead(UserListPath));

        while(!userReader.EndOfStream)
        {
            var line = userReader.ReadLine();
            var newUser = new User();
            if(line.Contains("DeltaV User List"))
            {
                var Area = userReader.ReadLine();
                newUser.Area = Area;
                userReader.ReadLine();
                userReader.ReadLine();
                userReader.ReadLine();

                var userid = userReader.ReadLine();
                Console.WriteLine(userid);
                var name = userid.Split(' ');
                Console.WriteLine(name[0]);
                newUser.UserId = name[0];
            }
            Users.Add(newUser);
        }

哦,我只需要获取UserId,而不是全名。

3 个答案:

答案 0 :(得分:1)

<强>被修改

这里有一小段代码可以满足您的需求:

        using (var fileStream = File.OpenRead(UserListPath))
        using (var userReader = new StreamReader(fileStream))
        {
            string currentArea = string.Empty;
            string currentToken = string.Empty;
            while (!userReader.EndOfStream)
            {
                var line = userReader.ReadLine();
                if (!string.IsNullOrEmpty(line))
                {
                    var tokenFound = Tokens.FirstOrDefault(x => line.StartsWith(x));
                    if (string.IsNullOrEmpty(tokenFound))
                    {
                        switch (currentToken)
                        {
                            case AreaToken:
                                currentArea = line.Trim();
                                break;
                            case UserToken:
                                var array = line.Split(' ');
                                if (array.Length > 0)
                                {
                                    Users.Add(new User()
                                    { 
                                        Name = array[0],
                                        Area = currentArea
                                    });
                                }
                                break;
                            default:
                                break;
                        }
                    }
                    else
                    {
                        currentToken = tokenFound;
                    }
                }
            }
        }

此程序假定您的输入文件以换行符结束。它使用这些常量,您必须通过修改其访问者(例如privatepublic)在您的课堂或任何您想要的地方声明:

private const string AreaToken = "DeltaV";
private const string UserToken = "UserID";

private List<string> Tokens = new List<string>() { AreaToken, UserToken };

当然,我已经按照自己的方式做到了,可能还有很多更好的方法。以你想要的方式改进它,它只是一种应该编译和工作的草稿。

除此之外,您还会注意到:

  • 使用using关键字,这对于确保您的内存/资源/文件句柄正确免费非常有用。
  • 我试图避免使用硬编码值(这就是我使用常量和参考列表的原因)
  • 我试图制作它,所以你只需要在令牌参考列表中添加新的常量(称为Tokens)并扩展开关案例以处理新的文件令牌/场景

最后,不要忘记实例化您的User列表:

List<User> Users = new List<User>();

答案 1 :(得分:1)

以下是我的工作:

void Main()
{
    var filePath = @"..."; //insert your file path here
    var lines = File.ReadLines(filePath); //lazily read and can be started before file is fully read if giant file

    IList<User> users = new List<User>();
    var Area = string.Empty;
    foreach(var line in lines)
    {
       if(string.IsNullOrWhiteSpace(line) || 
           line.Contains("DeltaV User List") ||
           line.Contains("UserID")
          )
       {
          continue;
       }


    var values = line.Split(' ');
    if(values.Length == 1)
    {
          Area = values[0];
          continue;
    }

    var currentUser = new User
    {
          Name = values[0],
          Area = Area
    };
    users.Add(currentUser);
  }
    users.Dump("User List"); //Dump is a Linqpad method to display result see screen shot
}

// Define other methods and classes here
public class User
{
    public string Name { get; set; }
    public string Area { get; set; }
}

您发布的文件的结果: User Result

File.ReadLines

LinqPad用于测试小代码片段。

您可以将其复制并粘贴到LinqPad中以根据需要进行修改,只需提供一个文件即可。

答案 2 :(得分:1)

    // read user list text file
    var userReader = new StreamReader(File.OpenRead(UserListPath));
    var Area = "";
    while(!userReader.EndOfStream)
    {
        var line = userReader.ReadLine();
        if(line.Contains("DeltaV User List"))
        {
            Area = userReader.ReadLine();  // Area applies to group of users below.
            userReader.ReadLine(); // blank line
            userReader.ReadLine(); // blank line
            userReader.ReadLine(); // User ID header line
        }
        else
        {
            if (line.trim() != "") // Could be blank line before "DeltaV..." 
            {
                var userid = line;
                var newUser = new User();
                newUser.Area = Area;
                // I left the following lines in place so that you can test the results.
                Console.WriteLine(userid);
                var name = userid.Split(' ');
                Console.WriteLine(name[0]);
                newUser.UserId = name[0];
                Users.Add(newUser);
            }
        }
    }