2016-11-04 4 views
1

Как вы соответствуете повторяющейся группе в повторяющейся группе?Regex: получить вложенную повторяющуюся группу

Например получать все действительные записи в лог-файле:

---: 
TS : 150602000006S 
EC1: 02429.523 
EC2: 05604.110 
--- 
---: 
TS : 150603000006S 
---: 
TS : 150603000006S 
EP1: 3333.523 
--- 

Как следующие матчи:

[ 
    [ 
    ['TS ', '150602000006S'], 
    ['EC1', '02429.523'], 
    ['EC2', '05604.110'] 
    ], 
    [ 
    ['TS', '150603000006S'], 
    ['EP1', '3333.523'] 
    ] 
] 

Извлечение отдельных записей свойств может быть сделано с (See on regex101):

([A-Z0-9 ]{3,3}): ([0-9SW]+)?([0-9\.SW]{3,})\n 

Однако, при размещении регулярных выражений в группе записей (like seen here) группы свойств перестают сопоставляться повторяющимся образом.

Как это правильно сделано?

+1

Вероятно не с регулярным выражением ... – Mena

+0

@Mena Почему это невозможно? – JasperJ

+0

Я не говорю, что это категорически невозможно, но в целом регулярные выражения хороши для разбора текста, а не контекстно для данной грамматики (например, регулярное выражение против разметки, как правило, очень плохое представление). Когда у вас есть вложенные элементы и правила для вложенности, регулярные выражения становятся очень громоздкими очень скоро. Предполагая, что вы находите правильный способ сопоставления с вашими иерархическими записями, само выражение будет длинным, вероятно, нечитаемым и очень сложно поддерживать. Обычно для этого нужно реализовать собственный синтаксический анализатор. – Mena

ответ

1

Чтобы сохранить эту поддержку, я попытался бы разбить ее на несколько регулярных выражений.

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

---:\n 
---(\n|$) 

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

---:\n.*?---(\n|$) 

Это представляет собой буквальный ---: с последующим переводом строкой, а затем как можно меньше текста, насколько это возможно (*? лень), а затем либо новой строкой или концом строки. Вам нужно будет запустить этот флаг s.

Это даст вам три матча на вашей примерной строке. Затем вы можете запустить свой шаблон на каждом из итоговых совпадений.


* Отказ может показаться, как легкий путь здесь, но это трудно делать какие-либо точные догадываются о неправильно отформатированных данных. Учитывая ваш предыдущий пример, у нас есть два выбора, если мы хотим, чтобы нормализовать эти данные, как добавили в комментариях:

---: 
TS : 150602000006S 
EC1: 02429.523 
EC2: 05604.110 
--- 
---: 
TS : 150603000006S 
     // Add a closing tag here? 
---: // Remove this opening tag? 
TS : 150603000006S 
EP1: 3333.523 
--- 

Каковы последствия, если мы предполагаем, неправильно? Есть ли какие-либо преимущества для продолжения при наличии ошибок? Это будет полностью зависеть от вашего приложения.

+0

Я согласен с разделением регулярного выражения на две части. И это соответствует отдельным записям, однако он не заботится о недопустимых записях [см. Здесь] (https://regex101.com/r/Rlw2tn/1).Есть ли регулярное выражение для этого? – JasperJ

+0

@ JasperJ Я внесла поправки в свой ответ. Надеюсь, поможет. – Michael

Смежные вопросы