Regex .net 仅从订单项列表中获取最后一个匹配项
Regex .net Only getting last match from line item list
我不常使用正则表达式。我正在尝试从字符串中获取部件号。到目前为止,我已经度过了一天。
我希望 "Line"
有 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`
编辑以更好地说明我的问题
作为第一步,您似乎忽略了重复语法,作为副产品,这使得之后更难获得捕获组。也就是说,这部分:
(?<PartNo>[a-zA-Z0-9-]*)__
应该看起来更像这样:
((?<PartNo>[a-zA-Z0-9-]*)__)+
+
表示您希望找到其中的 1 个或多个,__ 包含在外部捕获组中,因为您需要它们一直延伸到最后一个零件号,而 non-__ 字符在它们自己的内部捕获组中,因此您可以提取它们。
如果您确定总会有零件号,我会把 ?
放在内部捕获组中,从技术上讲它与 +
相矛盾,虽然这看起来并不当我尝试它时(在 Notepad++ 中)很重要,没有必要混淆这个问题。
看来你需要对捕获组身份进行一些仔细的 post-捕获评估,尽管我不使用像 <PartNo>
这样的别名,所以我不能说当然,也许没那么难。
您的正则表达式 (?<PartNo>[a-zA-Z0-9-]*)\S
的这一部分捕获名为 PartNo
的组并匹配 [a-zA-Z0-9-]*
后跟 \S
,它不匹配空白字符,但根据您的示例数据应该是 \s
匹配空白字符
你只得到最后一场比赛,因为你是 repeating the capturing group。
如果您希望有 2 场比赛,您可以在与 PartNo
相同的组中捕获 OrderQuantity
。
使用 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
另一种选择是使用 PartNo
和 OrderQuantity
regex demo or without the OrderQuantity
group regex demo
的多个命名捕获组
我不常使用正则表达式。我正在尝试从字符串中获取部件号。到目前为止,我已经度过了一天。
我希望 "Line"
有 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`
编辑以更好地说明我的问题
作为第一步,您似乎忽略了重复语法,作为副产品,这使得之后更难获得捕获组。也就是说,这部分:
(?<PartNo>[a-zA-Z0-9-]*)__
应该看起来更像这样:
((?<PartNo>[a-zA-Z0-9-]*)__)+
+
表示您希望找到其中的 1 个或多个,__ 包含在外部捕获组中,因为您需要它们一直延伸到最后一个零件号,而 non-__ 字符在它们自己的内部捕获组中,因此您可以提取它们。
如果您确定总会有零件号,我会把 ?
放在内部捕获组中,从技术上讲它与 +
相矛盾,虽然这看起来并不当我尝试它时(在 Notepad++ 中)很重要,没有必要混淆这个问题。
看来你需要对捕获组身份进行一些仔细的 post-捕获评估,尽管我不使用像 <PartNo>
这样的别名,所以我不能说当然,也许没那么难。
您的正则表达式 (?<PartNo>[a-zA-Z0-9-]*)\S
的这一部分捕获名为 PartNo
的组并匹配 [a-zA-Z0-9-]*
后跟 \S
,它不匹配空白字符,但根据您的示例数据应该是 \s
匹配空白字符
你只得到最后一场比赛,因为你是 repeating the capturing group。
如果您希望有 2 场比赛,您可以在与 PartNo
相同的组中捕获 OrderQuantity
。
使用 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
另一种选择是使用 PartNo
和 OrderQuantity
regex demo or without the OrderQuantity
group regex demo