Регулярное выражение: необязательная группа не работает - PullRequest
0 голосов
/ 26 мая 2020

У меня есть этот regEx:

\ 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 +). +? (?: Дата доставки: \ 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

. . . некоторый текст

Ihre Art.-Nr. 1690431

Дата доставки: 21.11.2019

. . . некоторый текст

вкл. 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 +). +? (?: Дата доставки: \ s (\ d {2}. \ d {2}. \ d {4})) ? . +? (?: ExtraCharge. +? Entspricht: \ s (\ d {0,3} (. \ D {3}) , \ d ) \ s (\ w {1,10})) ?

но это не работает, и я не знаю почему

Ответы [ 2 ]

1 голос
/ 26 мая 2020

Вместо использования .+? вы можете сопоставить отдельные части, проверяющие значения в начале строки, используя отрицательный прогноз. (?!

Кажется, что денежные значения всегда заканчиваются на запятую, вместо использования \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

1 голос
/ 26 мая 2020

Если (?:DeliveryDate:\s(\d{2}.\d{2}.\d{4}))? не соответствует, то регулярное выражение по-прежнему ожидает, что .+? до и после по-прежнему будут совпадать.

Попробуйте поместить окончание .+? внутри группы без захвата, которая у вас есть для DeliveryDate. например,

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

...