Регулярное выражение для соответствия определенным строкам, но только первая строка в новой строке - PullRequest
0 голосов
/ 26 сентября 2019

Используя Python regex, я пытаюсь разобрать некоторые сценарии Behat.Вот регулярное выражение: https://regex101.com/r/EGdK3O/1 (Scenario:([\s\S]*?)(And|When|Then|Given)).

Текущая версия моего кода items = re.findall(r'Scenario:([\s\S]*?)(And|When|Then|Given|#)', contents, re.MULTILINE).Это работает, за исключением случаев, когда одна из этих строк находится в сценарии.

Мне трудно понять, как сопоставлять (And|When|Then|Given), только когда вхождение строки является первой строкой в ​​новой строке.Еще лучше было бы, если бы я мог сопоставить новую строку, в которой есть табуляция или количество пробелов.

Конечная цель здесь - получить описание сценария, но не шаги.

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019

, даже если у вас может возникнуть какое-то очень сложное регулярное выражение для разбора языка Behat, это типичный случай «У меня была одна проблема, я использовал регулярное выражение, теперь у меня 2 проблемы» :

Вместо того, чтобы сойти с ума, пытаясь решить эту проблему с помощью регулярных выражений, вам лучше использовать библиотеку, которая может читать и анализировать язык Behat.

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

Типичная проблема (с которой вы сталкиваетесь) - это когда слово имеет другое значениеучитывая контекст, и грамматика там, чтобы помочь в этом.И даже несмотря на то, что вы можете выяснить первый шаг разбора сценариев, при рассмотрении каждого сценария у вас, скорее всего, возникнет похожая проблема.

Поэтому вам необходимо реализовать полномасштабный сценарий.парсер… Но написание парсера нелегко (самая сложная часть - написание грамматики).Так что, если вы Люси, кто-то другой сделал это для вас!

И вам повезло!Посмотрев на некоторую документацию по Behat , используемый язык называется gherkin.С некоторым поиском я нашел по крайней мере один пакет на python, который понимает этот язык: cucumber/gherkin-python, который теперь перемещен в репозиторий cucumber/cucumber.

Ниже приведен фрагмент использования парсера:

from gherkin.parser import Parser
from gherkin.pickles.compiler import compile

parser = Parser()
gherkin_document = parser.parse("Feature: ...")
pickles = compile(gherkin_document)

Затем вы получите структурированный вывод данных, через который вы сможете легко перемещаться в python.

1 голос
/ 26 сентября 2019

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

Затем используйте одну группу захвата, чтобы повторить сопоставление строк, которые не начинаются с (And|When|Then|Given), с добавлением 1+ табуляции или пробелов, и, наконец, сопоставить строку, содержащую один из параметров после группы захвата.

\bScenario:(.*(?:\r?\n(?![ \t]+(And|[WT]hen|Given)).*)*)\r?\n[ \t]+(?:And|[WT]hen|Given)
  • \bScenario: Соответствие Scenario: с добавлением границы слова
  • ( Захват группа 1
    • .* Соответствиелюбой символ, кроме новой строки
    • (?: Группа без захвата
      • \r?\n Соответствует новой строке
      • (?! Отрицательный прогноз, если справа нет [ \t]+(And|[WT]hen|Given) Совпадение с 1+ пробелами или символами табуляции и 1 из опций
      • ).* Закрыть группу и сопоставить 0+ раз с любым символом, кроме новой строки
    • )* Закрытьгруппировать и повторять 0+ раз
  • ) Закрыть группу захвата
  • \r?\n[ \t]+ Соответствовать новой строкой и 1+ пробелами или символами табуляции
  • (?:And|[WT]hen|Given) Соответствует любому из перечисленных

Regex demo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...