正则表达式.net仅从订单项列表中获取最后一个匹配项

时间:2018-12-12 20:29:53

标签: .net regex nsregularexpression

我不太使用Regex。我正在尝试从字符串中获取零件号。到目前为止,我已经呆了一天。

我预计“线”有2个匹配项

 __40X0343 1.00
 __C734X77G 2.00

在那些比赛中,我希望这些比赛

PartNo 40X0343 OrderQuantity 1.00 for Line 1
PartNo C734X77G OrderQuantity 2.00 for Line 2

但是我只能获得最后一场比赛,而不是两者。任何帮助都很好

正则表达式:

(?x)Required\sDate
(?<Line>__
(?<PartNo>[a-zA-Z0-9-]*)\S
(?<OrderQuantity>[0-9.]+)
)*

字符串

__Required Date__40X0343 1.00__C734X77G 2.00__Net Order:__Sales Tax:__Freight:__Order Total:__0.00 __0.00 __5,328.50 __5,328.50 __or by fax  

来自正则表达式工具的结果

Full match 2-44 `Required Date__40X0343 1.00__C734X77G 2.00` 
Group `Line` 29-44 `__C734X77G 2.00` 
Group `PartNo` 31-39 `C734X77G` 
Group `OrderQuantity` 40-44 `2.00` 

编辑以更好地说明我的问题

2 个答案:

答案 0 :(得分:0)

作为第一步,您似乎正在省略重复语法,并且作为副产品,这使得以后更难捕获组。换句话说,这部分是:

    (?<PartNo>[a-zA-Z0-9-]*)__

应该看起来像这样:

    ((?<PartNo>[a-zA-Z0-9-]*)__)+

+意味着您希望找到其中的一个或多个,__包含在外部捕获组中,因为您需要它们一直扩展到最后一个零件号,并且非__字符在它们自己的内部捕获组中,因此您可以提取它们。

如果您确定总会有零件号,则将?放到内部捕获组中,从技术上讲,它与+相矛盾,尽管这似乎无关紧要当我尝试过(在Notepad ++中)时,毫无疑问会混淆该问题。

您似乎需要对捕获组身份进行一些仔细的捕获后评估,尽管我没有使用<PartNo>之类的别名,所以我不能肯定地说,也许不是好难。

答案 1 :(得分:0)

正则表达式(?<PartNo>[a-zA-Z0-9-]*)\S的这一部分捕获了一个名为PartNo的组,并与[a-zA-Z0-9-]*匹配,后跟\S,它们不匹配空格字符,但根据您的示例数据应该是\s,与空格字符匹配

由于您是repeating the capturing group,因此您只能获得最后一场比赛。

如果您希望获得2个匹配项,则可以将OrderQuantityPartNo放在同一组中。

使用C#,您可以使用Group.Captures并使用组名PartNo。然后,您可以获取捕获并将其循环。

例如:

string pattern = @"(?x)Required\sDate
(?<Line>__
(?<PartNo>[a-zA-Z0-9-]*\s[0-9.]+)
)*";
string str = @"__Required Date__40X0343 1.00__C734X77G 2.00__Net Order:__Sales Tax:__Freight:__Order Total:__0.00 __0.00 __5,328.50 __5,328.50 __or by fax";        
Regex regex = new Regex(pattern);
MatchCollection matchColl = regex.Matches(str);
if (matchColl != null) 
    foreach (Match match in matchColl) 
        foreach (Capture c in match.Groups["PartNo"].Captures) 
            Console.WriteLine(c.Value);

结果

40X0343 1.00
C734X77G 2.00

请参见C# demo

另一种选择是使用PartNoOrderQuantity regex demo或不包含OrderQuantityregex demo

的多个命名捕获组。