我目前正在尝试解析包含以下信息的.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()实用的常见分隔符。任何有关如何实现这一目标的帮助或见解将不胜感激。
答案 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)
有很多方法可以解决这个问题,但最重要的是你需要考虑字符串格式的变化,这可能会使任何一种方法绊倒
以下是一些假设的方法。您必须根据您的假设调整代码以及这段代码的重要性。
// 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了解可能尝试更严格变体的正则表达式