如何创建正则表达式来解析按关键字

时间:2017-08-02 18:58:10

标签: c# regex

我正在努力让正则表达式工作。我想解析像这样的列表

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循环的选项,但我真的想学习如何使用正则表达式。请帮我写这个正则表达式。

2 个答案:

答案 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});
}