#regex #regex-group
#регулярное выражение #регулярное выражение-группа
Вопрос:
Вот допустимое выражение дерева свойств (оно может быть рекурсивным):
rootProperty:(prop1, prop2, subProp1:(prop1,subprop1:(prop1, prop2 и т. Д.), prop3), prop3 и т. Д.)
Таким образом, свойство может иметь множество свойств и вложенных свойств. Из этого выражения я хотел бы получить следующее:
- rootProperty
- prop1
- prop2
- subProp1:(prop1,subprop1:(prop1, prop2 и т. Д.), prop3)
- prop3
Я попробовал несколько подходов, но не смог заставить повторения работать рекурсивно. Следовательно, ищу помощь.
Спасибо Kannan
Комментарии:
1. Можете ли вы показать, что вы пробовали до сих пор?
2. И регулярные выражения, как правило, не подходят для рекурсивных структур, так что, вероятно, это не лучший подход в любом случае.
3. привет, Джоанис, я согласен, я думаю, что регулярное выражение может быть неправильным выбором для этой рекурсивной структуры. Возможно, мне придется найти альтернативный способ обхода дерева свойств.
Ответ №1:
Это не обычный язык из-за рекурсии (сбалансированные скобки), поэтому регулярное выражение может быть не тем, что вам нужно. Но предполагая, что вы знаете, что делаете:
([^:(), ] )(?::(((?R)?(?:, ?(?R))*)))?
Сначала мы фиксируем имя свойства: один или несколько символов, которые не :(),
являются.
([^:(), ] )
Свойство может иметь или не иметь поддерево, поэтому следующая часть — необязательное поддерево:
(?: <--- do not capture
: <--- literal ':'
( <--- literal '('
... <--- some stuff inside
) <--- literal ')'
)? <--- it is optional
Содержимое внутри содержит список свойств:
( <--- do capture
(?R) <--- recursively match a property
(?: <--- do not capture
, ? <--- comma followed by optional space
(?R) <--- recursively match another property
)* <--- any number of comma separated properties
) <--- end capture
Для вашего примера ввода:
Input:
rootProperty:(prop1, prop2, subProp1:(prop1,subSubProp1:(prop1,prop2,etc),prop3), prop3, etc)
Match 1:
rootProperty:(prop1, prop2, subProp1:(prop1,subSubProp1:(prop1,prop2,etc),prop3), prop3, etc)
Group 1:
rootProperty
Group 2:
prop1, prop2, subProp1:(prop1,subSubProp1:(prop1,prop2,etc),prop3), prop3, etc
Затем вы можете рекурсивно сопоставить вторую группу каждого соответствия для получения свойств поддерева. Должен быть способ получить информацию об обратном отслеживании, чтобы вам не нужно было этого делать, но я не знаю как.
Input:
prop1, prop2, subProp1:(prop1,subSubProp1:(prop1,prop2,etc),prop3), prop3, etc
Match 1:
prop1
Match 2:
prop2
Match 3:
subProp1:(prop1,subSubProp1:(prop1,prop2,etc),prop3)
Group 1:
subProp1
Group 2:
prop1,subSubProp1:(prop1,prop2,etc),prop3
Match 4:
prop3
Match 5:
etc
Затем,
Input:
prop1,subSubProp1:(prop1,prop2,etc),prop3
Match 1:
prop1
Match 2:
subSubProp1:(prop1,prop2,etc)
Group 1:
subSubProp1
Group 2:
prop1,prop2,etc
Match 3:
prop3
И, наконец,:
Input:
prop1,prop2,etc
Match 1:
prop1
Match 2:
prop2
Match 3:
etc
Комментарии:
1. Большое спасибо, это сработало бы для меня. Я раньше не использовал ‘?R’. Если что-либо, кроме конечных свойств, я буду вызывать функцию parse рекурсивно для анализа вложенного вложенного свойства. Я попробую это в своем коде. Еще раз спасибо.
2. Вау, я поражен этим решением. При такой рекурсии мы теперь говорим о контекстно-свободной грамматике. Современные библиотеки RE в языках программирования уже давно не являются технически регулярными, но это делает еще один удивительный шаг вперед. Мне нужно изучить этот инструмент, но вау, это REs на серьезных наркотиках!