couatl
@couatl

Шаблоны (группировка) в регулярных выражениях и сохранение не только первого вхождения

В регулярных выражениях есть такое понятие как группировка, помогающая вытащить с помощью регулярного выражения сразу несколько частей. Она обозначается через круглые скобки.
Дело в том что сохраняется лишь первое вхождение. Вот пример:
str = Mama mila ramu
regex = (?:([A-Za-z]+)\s?)+


Вот результат:
0: (Mama mila ramu) // тут вопросов нет, выражение как раз выдирает всю строку
1: (ramu) // вот оно первое вхождение


Можно ли как-нибудь с помощью группировки выдирать не только первое вхождение, а все?
То есть требуемый результат:
0: (Mama mila ramu)
1: (Mama)
2: (mila)
3: (ramu)


Естественно все это делается не для этого примера.
Мой пример где я столкнулся с этой проблемой:
Имеется КС-грамматика и ее правила
S->a|AS
A->AB
B->b

Одним регулярным выражением хочется установить — является ли правило корректным и выдрать все из правила.
Написал такое регулярное выражение: \b([A-Z])->(?:([A-Za-z]+)\|?)+
Но естественно из правой части она достает с помощью группировки только первое вхождение.
Результат для S->a|AS:
0: (S->a|AS)
1: (S)
2: (AS)

а нужно
0: (S->a|AS)
1: (S)
2: (a)
3: (AS)
  • Вопрос задан
  • 6768 просмотров
Пригласить эксперта
Ответы на вопрос 2
Wott
@Wott
можно, просто для этого обычно отдельный вызов/синтаксис
язык какой?
Ответ написан
Weageoo
@Weageoo
По-хорошему, нужно воспользоваться к.-л. генератором компиляторов, описав грамматику в BNF или EBNF. Регулярные выражения не обеспечят необходимой гибкости.

Более-менее, если язык простенький, регулярками можно выделить лексемы (разбить выражение). Проверять корректность надо бы синтаксическим анализатором.

Конкретно для вашего случая что-то вроде (Python):

>>> import re
>>> re.findall("^(([A-Z])->([A-Za-z]+)\|([A-Z]+))", «S->a|AS»)
[('S->a|AS', 'S', 'a', 'AS')]

Или re.match(...).group(n) юзать…
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы