Регулярное выражение для разбора данных, разделенных скобками - PullRequest
0 голосов
/ 20 декабря 2018

Мне нужно регулярное выражение для анализа некоторых данных, разделенных на квадратные скобки.

Каждые данные содержат 3 раздела с фиксированными именами и предустановленным порядком , которые можно сравнить с приемом пищи.(Идентификаторы разделов: <br />[Breakfast]<br />, <br />[Lunch]<br />, <br />[Dinner]<br />)

Но проблема в том, что некоторые или все разделы каждого из данных могут не существовать , как проиллюстрировано ниже, а содержимое может содержать пары скобок для предоставленияДополнительная информация.(но никогда не содержит идентификаторов внутри.)

Пример данных:

  • 20181225<br />[Breakfast]<br />Fish finger sandwich [400 kcal]<br />Jellied eels<br />[Lunch]<br />Pork pies [500 kcal]<br />[Dinner]<br />Stargazy pies
  • 20181226<br />[Dinner]<br />Stargazy pies
  • 20181227<br />[Breakfast]<br />Fish finger sandwich [400 kcal]<br />Jellied eels<br />[Dinner]<br />Stargazy pies
  • 20181228

Желаемый выход: $date: 20181225$breakfast: Fish finger sandwich [400 kcal]<br />Jellied eels$lunch: Pork pies [500 kcal]$dinner: Stargazy pies

$date: 20181226$dinner: Stargazy pies

$date: 20181227$breakfast: Fish finger sandwich [400 kcal]<br />Jellied eels$dinner: Stargazy pies

$date: 20181228

Я попробовал регулярное выражение ниже, но не работает должным образом, так как жадный квантификатор игнорирует следующие разделы, даже если они существуют .

(?<date>\d{8})(?:<br \/>\[Breakfast\]<br \/>(?<breakfast>.*))?(?:<br \/>\[Lunch\]<br \/>(?<lunch>.*))?(?:<br \/>\[Dinner\]<br \/>(?<dinner>.*))?

Заранее спасибо.

1 Ответ

0 голосов
/ 20 декабря 2018

Один из вариантов будет в конце каждой необязательной группы искать $ или <br сразу после лениво-повторяющегося ..Также прикрепите конец совпадения к концу строки, чтобы обеспечить сопоставление каждой подгруппы, которая может быть сопоставлена:

(?<date>\d{8})(?:<br \/>\[Breakfast\]<br \/>(?<breakfast>.*?(?=$|<br)))?(?:<br \/>\[Lunch\]<br \/>(?<lunch>.*?(?=$|<br)))?(?:<br \/>\[Dinner\]<br \/>(?<dinner>.*))?$
                                                           ^^^^^^^^^^

https://regex101.com/r/vtCLoX/1

Если вы можетене рассчитывайте на строку, содержащую только эти данные, тогда использование $ s не сработает - вместо этого, после Breakfast, повторите, убедившись, что вы не встретите Lunch|Dinner,и после Lunch повторите, убедившись, что вы не встретите Dinner:

(?<date>\d{8})(?:<br \/>\[Breakfast\]<br \/>(?<breakfast>(?:(?!<br \/>\[(Lunch|Dinner)\]).)+))?(?:<br \/>\[Lunch\]<br \/>(?<lunch>(?:(?!<br \/>\[Dinner).)+))?(?:<br \/>\[Dinner\]<br \/>(?<dinner>.*))?
                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                      ^^^^^^^^^^^^^^^^^^^^^^^^^

https://regex101.com/r/vtCLoX/3

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...