如何在C#中使用不常见的分隔符解析.txt文件

时间:2018-03-30 02:17:13

标签: c# parsing split text-files delimiter

我目前正在尝试解析包含以下信息的.txt文件:name / ID number / email / GPA。以下是几行显示文本文件的样子。

(列表(列''Doe'Jane'F)'8888675309'jfdoe@mail.university.edu 2.3073320999676614)

(列表('Doe'John'F''无''johnfdoe@mail.university.edu 3.1915725161177115)

(列表(列''Doe'Jim'F)'8885551234'jimdoe@mail.university.edu 3.448215586562192)

在我当前的代码中,我所做的就是将文本文件逐行打印到控制台窗口。

static void Main(string[] args)
    {

        StreamReader inFile;
        string inLine;

        if (File.Exists("Students.txt"))
        {
            try
            {
                inFile = new StreamReader("Students.txt");
                while ((inLine = inFile.ReadLine()) != null)
                {
                    Console.WriteLine(inLine);

                }
            }
            catch (System.IO.IOException exc)
            {
                Console.WriteLine("Error");

            }
            Console.ReadLine();
        }
    }

例如,我需要能够找到GPA高于3.0的所有学生,并将他们的姓名和GPA打印到另一个文本文件中。我知道如何打印到另一个文件,但是,我不确定如何访问各个列,例如GPA,因为这个文件似乎没有任何使用Split()实用的常见分隔符。任何有关如何实现这一目标的帮助或见解将不胜感激。

3 个答案:

答案 0 :(得分:2)

重要

我认为您问题中提供的字符串具有固定格式,如图所示。

<强>实施

首先,您需要创建一个类,该类是您从字符串中获取的信息的蓝图。它将为您提供一个容器来保存有关数据的有意义的信息。

public class StudentInfo
{
    public string Name { get; set; }
    public string Number { get; set; }
    public string Email { get; set; }
    public double GPA { get; set; }
}

以下是如何解析字符串(来自您的问题的字符串)并将其转换为相关信息的示例。我假设你可以用C#读/写文件。 此示例演示如何在List中解析和存储iformation。您可以进一步使用它来编写文件。

在您的代码中,您正在读取行,这就是为什么在此示例中,我尝试从字符串中读取行以便您更好地理解它。

我在C#Console应用程序中创建了此示例。

static void Main(string[] args)
{
    List<StudentInfo> studentInfo = new List<StudentInfo>();

    string input = "(LIST(LIST 'Abbott 'Ashley 'J ) '8697387888 'ajabbott@mail.university.edu 2.3073320999676614 )" + Environment.NewLine +
    "(LIST(LIST 'Abbott 'Bradley 'M ) 'NONE 'bmabbott@mail.university.edu 3.1915725161177115 )" + Environment.NewLine +
    "(LIST(LIST 'Abbott 'Ryan 'T ) '8698689793 'rtabbott@mail.university.edu 3.448215586562192 )";

    string[] lines = input.Split(new[] { Environment.NewLine }, StringSplitOptions.None);

    if (lines != null && lines.Count() > 0)
    {
        foreach (var line in lines)
        {
            var data = line.Replace("(LIST(LIST ", string.Empty)
                .Replace(")", string.Empty)
                .Replace("'", string.Empty)
                .Trim()
                .Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (data != null && data.Count() > 0)
            {
                studentInfo.Add(
                    new StudentInfo()
                    {
                        Name = data[0] + " " + data[1] + " " + data[2],
                        Number = data[3],
                        Email = data[4],
                        GPA = Convert.ToDouble(data[5])
                    });
            }
        }
    }

    // GET STUDENTS WHO GOT GPA > 3  (LINQ QUERY)
    if (studentInfo.Count > 0)
    {
        var gpaGreaterThan3 = studentInfo.Where(s => s.GPA >= 3).Select(s => s).ToList();

        if (gpaGreaterThan3 != null && gpaGreaterThan3.Count > 0)
        {
            // LOOP gpaGreaterThan3 TO PRINT STUDENT DATA
            foreach (var stud in gpaGreaterThan3)
            {
                Console.WriteLine("Name: " + stud.Name);
                Console.WriteLine("Number: " + stud.Number);
                Console.WriteLine("Email: " + stud.Email);
                Console.WriteLine("GPA: " + stud.GPA);
                Console.WriteLine(string.Empty);
            }
        }
    }

    Console.ReadLine();
}

答案 1 :(得分:0)

试试这个:

            var data = inLine.Replace("(LIST(LIST ", string.Empty)
                        .Replace(")", string.Empty)
                        .Replace("'", string.Empty)
                        .Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

答案 2 :(得分:0)

有很多方法可以解决这个问题,但最重要的是你需要考虑字符串格式的变化,这可能会使任何一种方法绊倒

  1. 是gpa字段始终存在还是最后?
  2. 是否有明确的可识别格式等
  3. 可以有不止一个,如果有,你会选择哪一个
  4. 以下是一些假设的方法。您必须根据您的假设调整代码以及这段代码的重要性。

        // split on both space and closing bracket
        // Assumption: GPA field is present and at the end
        Console.WriteLine(line.Split(new[] { " ", ")" }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault());
    
        // regex for gpa defined as digit followed by literal . followed by one or more digits
        // Assumption: GPA field is present once somewhere in the string.
        // No other token conflicts with similar format
        var gpaRegex = new Regex(@"\d\.\d+");
        Console.WriteLine(gpaRegex.Matches(line)[0]);
    

    请参阅https://dotnetfiddle.net/6Xy0uW了解工作示例

    请参阅https://regex101.com/r/P1D7zf/1了解可能尝试更严格变体的正则表达式