正则表达式,包含所有行的内嵌捕获,直到达到指定的行文本值/自定义EOF标记

时间:2017-01-19 20:01:05

标签: c# regex

我有一些缩进的文字,如下所示:

Foo
    Bar
    Fizz
Buzz
EndOfData
Foo
    Bar
    Fizz
Buzz

我想捕获每一行的前导空格和行的其余部分,但只能到达EndOfData

我可以使用^( *)(.*)$捕获空白区域和余数,但我无法弄清楚如何阻止正则表达式处理超出EndOfData行。

我期待4场主赛,每场有2场次赛。

1 个答案:

答案 0 :(得分:0)

在C#中,您可以获得EndOfData行的第一个索引,然后使用正则表达式获取所需的数据:

using System;
using System.Linq;
using System.IO;
using System.Text.RegularExpressions;
public class Test
{
    public static void Main()
    {
        var s = "Foo\r\n    Bar\r\n    Fizz\r\nBuzz\r\nEndOfData\r\nFoo\r\n    Bar\r\n    Fizz\r\nBuzz";
        var res = Regex.Matches(s.Substring(0, s.IndexOf("\nEndOfData\r\n")), @"^(\p{Zs}*)(.*)\r$", RegexOptions.Multiline)
            .Cast<Match>()
            .Select(m => new[] { m.Groups[1].Value, m.Groups[2].Value });
        foreach (var v in res)
                Console.WriteLine("Group 1: '{0}', Group 2: '{1}'", v[0], v[1]);
    }
}

参见C#演示。

如果你真的想玩正则表达式,我可以建议一个基于lookbehind的方法,以确保当前行之前没有EndOfLine。这是可能的,因为.NET正则表达式中的lookbehind可以具有无限长度:

(?m)(?<!^EndOfData\r?\n(?s:.*?))^(?!EndOfData\r?$)( *)(.*)

请参阅regex demo

<强>详情:

  • (?<!^EndOfData\r?\n(?s:.*?)) - 匹配前面没有EndOfData
  • (?!EndOfData\r?$) - 该行不能等于EndOfData
  • ( *) - 零个或多个常规空格(替换为\p{Zs}以匹配除标签或标签之外的任何水平空格 - [\p{Zs}\t]
  • (.*) - 该行的其余部分(如果存在,则包括CR符号,如果您不希望在匹配组中使用CR,请使用([^\r\n]*)