我正在努力让正则表达式工作。我想解析像这样的列表
Teacher teacher name Class class name student full name 1 student full name 2 Teacher teacher name Class class name student full name 1 student full name 2 Class class name student full name 1 student full name 2 Teacher teacher name Class class name student full name 1 student full name 2
我想检索包含教师的组列表,每个教师包含一些课程,每个班级包含一些学生。 “教师”和“班级”这两个词是关键词。如果该行不属于此类,那么它将是前一课程的学生。
我最接近的是Teacher\t(.+?)\t*$(^Class\t(.+?)\t*$(^.+\t*$)*)*
没有成功。但它与“教师组”的内在内容不匹配
我总是有编写for循环的选项,但我真的想学习如何使用正则表达式。请帮我写这个正则表达式。
答案 0 :(得分:1)
您可以尝试使用以下正则表达式:
Teacher[ \f\t\v]([^\n\r]+)\r?\n(?:Class[ \f\t\v]([^\n\r]+)\r?\n(?:student[ \f\t\v]([^\n\r]+)\r?\n)*)*
然后,您可以使用群组和捕获来查找教师,班级和学生。要匹配哪个学生进入哪个班级,您必须检查捕获索引并对其进行适当排序。
答案 1 :(得分:1)
我认为你需要定义一个语法。考虑使用ANTLR或其他解析器生成器 但是,你可以通过正则表达式和C#
中的一些额外代码进行解析定义模型:
public class Teacher
{
public string Name { get; set; }
public List<Class> Classes { get; set; } = new List<Class>();
}
public class Class
{
public string Name { get; set; }
public List<Student> Students { get; set; } = new List<Student>();
}
public class Student
{
public string Name { get; set; }
}
然后解析你的输入:
var lineParser = new Regex("^(?<kind>Teacher|Class|)\\s*(?<name>[^$]+)");
var lines = input.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
.Select(line =>
{
var match = lineParser.Match(line);
var kind = match.Groups["kind"].Value;
var name = match.Groups["name"].Value;
return new { kind, name };
});
var teachers = new List<Teacher>();
foreach (var line in lines)
{
if (line.kind == "Teacher")
teachers.Add(new Teacher {Name = line.name});
else if (line.kind == "Class")
teachers.Last().Classes.Add(new Class {Name = line.name});
else
teachers.Last().Classes.Last().Students.Add(new Student {Name = line.name});
}