3.13.7. Рекурсия в регулярных выражениях

We use cookies. Read the Privacy and Cookie Policy

3.13.7. Рекурсия в регулярных выражениях

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

str = "а * ((b-c)/(d-e) - f) * g"

reg = /(?         # Начало именованного выражения.

       (         # Открывающая круглая скобка.

        (?:       # Незапоминаемая группа.

         (?>      # Сопоставление с собственническим выражением:

           \[()] # экранированная скобка

          |       # ЛИБО

           [^()]  # вообще не скобка. )

          )       # Конец собственнического выражения.

          |       # ЛИБО

          g      # Вложенная группа в скобках (рекурсивный вызов).

         )*       # Незапоминаемая группа повторяется нуль или

                  # более раз.

        )        # Закрывающая круглая скобка.

       )          # Конец именованного выражения.

      /x

m = reg.match(str).to_a # ["((b-c)/(d-e) - f)", "((b-c)/(d-e) - f)"]

Отметим, что левосторонняя рекурсия запрещена. Следующий пример допустим:

str = "bbbaccc"

re1 = /(?<foo>a|bg<foo>c)/

re1.match(str).to_a # ["bbbaccc","bbbaccc"]

А такой — нет:

re2 = /(?<foo>a|g<foo>c)/ # Синтаксическая ошибка!

Ошибка объясняется наличием рекурсивного обращения в начале каждой альтернативы. Немного подумав, вы поймете, что это приведет к бесконечному возврату.

Данный текст является ознакомительным фрагментом.