正则表达式将被捕获的组,直到到达另一个部分

时间:2018-08-28 22:20:18

标签: c# asp.net regex

试图找出一个RegEx来捕获一个组的多个实例,但只能捕获到某个特定点。

例如:

START

City: Los Angeles
- Item: 48
- Item: 57
- Item: 92
- Item: 77

City: Austin
- Item: 44
- Item: 88

END

我正在尝试编写一个正则表达式,将仅返回洛杉矶商品(例如:48,57,92,77)。下面的模式捕获了所有这些,但是我只想要洛杉矶。

 -\s*Item:\s*(?<itemnum>[0-9]{1,5})

1个正则表达式可能吗?

1 个答案:

答案 0 :(得分:2)

是的,您可以使用正则表达式,例如

(?m)^City:\s*Los Angeles(?:\s*-\s*Item:\s*(?<itemnum>\d+))+

请参见regex demo。您需要使用Regex.Matches并访问组“ itemnum”捕获堆栈以检索所有值。

模式详细信息

  • (?m)^-一行的开头
  • City:\s*Los Angeles-City:,0 +空格,Los Angeles
  • (?:\s*-\s*Item:\s*(?<itemnum>\d+))+-一种或多种情况:
    • \s*-\s*-一个-包含0+空格
    • Item:-文字Item:子字符串
    • \s*-超过0个空格
    • (?<itemnum>\d+)-组“ itemnum”:一位或多位数字。

请参见C# demo

var s = "START\r\n\r\nCity: Los Angeles\r\n- Item: 48\r\n- Item: 57\r\n- Item: 92\r\n- Item: 77\r\n\r\nCity: Austin\r\n- Item: 44\r\n- Item: 88\r\n";
var pattern = @"(?m)^City:\s*Los Angeles(?:\s*-\s*Item:\s*(?<itemnum>\d+))+";
var result = Regex.Matches(s, pattern)
   .Cast<Match>().SelectMany(p => p.Groups["itemnum"].Captures
        .Cast<Capture>()
        .Select(x => x.Value));
Console.WriteLine(string.Join(", ", result));
// => 48, 57, 92, 77

替代解决方案:使用基于\G的模式:

(?m)(?:^City:\s*Los Angeles|\G(?!\A))\s*-\s*Item:\s*(\d+)

请参见regex demo。基本上是相同的((?:^City:\s*Los Angeles|\G(?!\A))匹配City: Los Angeles,随后的匹配仅在上一个匹配结束位置的末尾才允许),但检索更容易:

var result = Regex.Matches(s, pattern)
   .Cast<Match>()
   .Select(p => p.Groups["itemnum"].Value)
   .ToList();