在正面观察后可能会有多次匹配(在自动换行之后)?

时间:2016-02-06 00:15:20

标签: c# regex

我是正则表达式的新手,并且遇到以下问题:

正在解析的文本文件:

KeywordA:   123
    93  0   0   524 0   0   78  0   0   6789    0   0
KeywordB:   456
    93  0   0   524 0   0   78  0   0   6789    0   0
KeywordC:   789
    93  0   0   524 0   0   78  0   0   6789    0   0

现在我想在#34; KeywordB:456"之后的下一行中获得2位或更多位数的所有数字。

我尝试了表达式/(?<=KeywordB:\t456\n\t)(\d{2,})/g

但是有了那个,我只得到第一个数字(并且只是因为93是一个多于一位的数字)。

甚至可以与RegEx进行所有适当的匹配,你希望在模式之后与模式进行多次匹配并进行自动换行或者我错过了一些基本的东西?

3 个答案:

答案 0 :(得分:2)

您可以使用the \G anchor在上一场比赛结束时继续匹配:

KeywordB:\t456\n|\G\t(?:(\d{2,})|\d)

.NET Fiddle Example Here

您还可以删除积极的外观,因为您只是检索第一个捕获组中的值。

<强>解释

  • KeywordB:\t456\n|\G - 匹配KeywordB:\t456\n或上一场比赛的开始(\G)。
  • \t - 在\t之后或上一场比赛结束时匹配标签KeywordB:\t456\n
  • (?: - 启动非捕获组。
  • (\d{2,})|\d - 捕获两个或多个数字的组匹配一个数字(换句话说,如果未捕获两个或多个数字,则匹配一个数字并继续前进)。
  • ) - 非捕获组的结束。

根据您提供的数据输出:

93
524
78
6789

上例中使用的代码段:

string pattern = @"KeywordB:\t456\n|\G\t(?:(\d{2,})|\d+)";
string input = @"KeywordA:  123
    93  0   0   524 0   0   78  0   0   6789    0   0
KeywordB:   456
    93  0   0   524 0   0   78  0   0   6789    0   0
KeywordC:   789
    93  0   0   524 0   0   78  0   0   6789    0   0";

foreach (Match match in Regex.Matches(input, pattern))
{
    string groupOne = match.Groups[1].Value;

    if (!string.IsNullOrEmpty(groupOne))
    {
        Console.WriteLine(groupOne);
    }
}

答案 1 :(得分:1)

使用.net,您可以使用可变长度的lookbehinds:

(?<=^KeywordB:\s*456\r?\n.*)\b\d{2,}

(使用多行选项)

demo

答案 2 :(得分:1)

我以为我会把它作为另一种选择,所以我知道这不是问题的直接答案。但是你能使用LINQ吗?

File
    .ReadAllLines("file.txt")
    .SkipWhile(line => line != "KeywordB:   456")
    .Skip(1)
    .Take(1)
    .SelectMany(line => line.Split(' ', '\t'))
    .Where(part => part.Length >= 2)
    .ToArray();

根据您的意见,我得到:

  

93,524,78,6789

我几乎总能找到比正则表达式更具可读性的LINQ解决方案。