Справка по регулярным выражениям, необходимая для анализа и извлечения свойства из дерева выражений

#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
 

https://regex101.com/r/WAXrFd/2

Комментарии:

1. Большое спасибо, это сработало бы для меня. Я раньше не использовал ‘?R’. Если что-либо, кроме конечных свойств, я буду вызывать функцию parse рекурсивно для анализа вложенного вложенного свойства. Я попробую это в своем коде. Еще раз спасибо.

2. Вау, я поражен этим решением. При такой рекурсии мы теперь говорим о контекстно-свободной грамматике. Современные библиотеки RE в языках программирования уже давно не являются технически регулярными, но это делает еще один удивительный шаг вперед. Мне нужно изучить этот инструмент, но вау, это REs на серьезных наркотиках!