正则表达式捕获简单的一级层次结构

时间:2017-06-27 08:45:54

标签: c# regex preg-match

我需要一个正则表达式来提取订单号和相应的订单行产品名称Order和OrderLine锚点是不变的。我设法编写了一个捕获订单的正则表达式,只捕获了第一个订单行。有人可以提出建议吗。

谢谢。

文件示例:

Order 123
OrderLine Some Product 1
OrderLine Some Product 2

Order 124
OrderLine Some Product 1
OrderLine Some Product 1

Some Text

1 个答案:

答案 0 :(得分:0)

重复捕获OrderLine(添加+或*修饰符)。

Group作为Captures属性,包含捕获组匹配的所有捕获。

在形式良好的文档中,组productNameproductQuantity将具有相同数量的捕获。你只需要迭代它。

var test = @"Order 123
OrderLine Apple Tree 1
OrderLine Ananas 2

Order 124
OrderLine Tree 1
OrderLine RainBow Warrior 1";


var regEx = new Regex(@"(Order (?<orderId>\d+)(?<orderLines>\s*OrderLine\s*(?<productName>.*)\s*(?<productQuantity>\d+))+)+");

var result = regEx.Matches(test);
foreach (Match match in result)
{
    var orderId = match.Groups["orderId"];
    var productNames = match.Groups["productName"].Captures;
    var productQuantities = match.Groups["productQuantity"].Captures;

    if (productNames.Count != productQuantities.Count)
    {
        throw new Exception();
    }

    Console.WriteLine($"Order {orderId}");
    for (var i = 0; i < productNames.Count; i++)
    {
        var productName = productNames[i].Value;
        var productQuantity = productQuantities[i].Value;
        Console.WriteLine($"  {productQuantity} | {productName}");
    }
}

输出:

Order 123
  1 | Apple Tree 
  2 | Ananas 
Order 124
  1 | Tree 
  1 | RainBow Warrior 

可悲的是,我找不到避免捕捉长度检查的方法。使用orderLines并且迭代它是不可能的,因为组不是匹配集合。