正则表达式:可选组不起作用

Regular Expression: optional group is not working

我有这个正则表达式:

\n1\s(\d{2,8})\s(\d{0,3}(.\d{3}),\d)\s(\w{1,10})\s(\d{0,3}(.\d{3}),\d)\s(\d{0,3}(.\d{3}),\d)\s(\w{3}).+?Ihre Art.-Nr.\s(\d+).+?(?:DeliveryDate:\s(\d{2}.\d{2}.\d{4})).+?(?:ExtraCharge.+?entspricht:\s(\d{0,3}(.\d{3}),\d)\s(\w{1,10}))

到目前为止工作正常。它匹配这样的东西:

1 123456 25,00 Stck 100,00 2.500,00 EUR

. . . some text

Ihre Art.-Nr. 1690431

DeliveryDate: 21.11.2019

. . . some text

incl.ExtraCharge

entspricht: 222,00 EUR

现在我希望粗体部分是可选的(在某些情况下文档中缺少值)。

我的想法是只在组中添加一个问号:

\n1\s(\d{2,8})\s(\d{0,3}(.\d{3}),\d)\s(\w{1,10})\s(\d{0,3}(.\d{3}),\d)\s(\d{0,3}(.\d{3}),\d)\s(\w{3}).+?Ihre Art.-Nr.\s(\d+).+?(?:DeliveryDate:\s(\d{2}.\d{2}.\d{4}))?.+?(?:ExtraCharge.+?entspricht:\s(\d{0,3}(.\d{3}),\d)\s(\w{1,10}))?

但是不行,不知道为什么

如果 (?:DeliveryDate:\s(\d{2}.\d{2}.\d{4}))? 不匹配,那么正则表达式仍然期望 .+? 前后仍然匹配。

尝试将结尾 .+? 放在 DeliveryDate 的非捕获组中。例如

(?:DeliveryDate:\s(\d{2}.\d{2}.\d{4}).+?)?

除了使用 .+?,您还可以使用否定先行 (?!

来匹配检查行开头值的单独部分

因为看起来像钱一样的值总是以逗号结尾,而不是使用 \d{0,3}(\.\d{3})*,\d* 这可能也匹配 .123, 你可以使用 \d{1,3}(?:\.\d{3})*(?:\,\d+) 代替。

假设 incl. 始终存在,您可以将其用作模式中的标记以至少匹配到该部分。

您仍然可以为 DeliveryDate 和 ExtraCharge 使用可选组

(?:DeliveryDate:\s(\d{2}.\d{2}.\d{4}))?(?:ExtraCharge\r?\n\s*entspricht:\s(\d{1,3}(?:\.\d{3})*(?:\,\d+))\s(\w{1,10}))?

整个模式可能如下所示:

\n1\s(\d{2,8})\s(\d{1,3}(?:\.\d{3})*(?:\,\d+))\s(\w{1,10})\s(\d{1,3}(?:\.\d{3})*(?:\,\d+))\s(\d{1,3}(?:\.\d{3})*(?:\,\d+))\s(\w{3})(?:\r?\n(?!Ihre).*)*\r?\nIhre Art.-Nr.\s(\d+)(?:\r?\n(?!DeliveryDate:|incl\.).*)*\r?\n(?:DeliveryDate:\s(\d{2}.\d{2}.\d{4}))?(?:\r?\n(?!incl\.).*)*\r?\nincl\.(?:ExtraCharge\r?\n\s*entspricht:\s(\d{1,3}(?:\.\d{3})*(?:\,\d+))\s(\w{1,10}))?

Regex demo