Как я могу сопоставить блок кода reStructuredText с Regex и Python?

Я пытаюсь извлечь code block из .rst документ с использованием Python и регулярных выражений. Блоки кода в документе определяются путем добавления .. code-block:: python директива к тексту, а затем отступ на несколько пробелов.

Вот пример из моего тестового документа:

.. code-block:: python

  import os
  from selenium import webdriver
  from axe_selenium_python import Axe

  def test_google():
      driver = webdriver.Firefox()
      driver.get("http://www.google.com")
      axe = Axe(driver)
      # Inject axe-core javascript into page.
      axe.inject()
      # Run axe accessibility checks.
      results = axe.execute()
      # Write results to file
      axe.write_results(results, 'a11y.json')
      driver.close()
      # Assert no violations are found
      assert len(results["violations"]) == 0,    axe.report(results["violations"])
      driver.close()

Пока у меня есть это регулярное выражение:(\.\. code-block:: python\s\s)(.*\s.+).*?\n\s+(.*\s.+)+

Проблема с этим шаблоном состоит в том, что он выбирает только первую часть и последнюю часть тестовой строки. Мне нужна помощь в написании шаблона, который может захватить все в пределах .. code-block:: python кодовый блок, исключая ..code-block:: python директивы.

Вы можете увидеть прогресс, которого я достиг с этим здесь.

1 ответ

Решение

Если вы настаиваете на использовании регулярных выражений, следующее должно помочь, учитывая приведенный пример:

import re

pattern = r"(\.\. code-block:: python\s+$)((\n +.*|\s)+)"

matches = re.finditer(pattern, text, re.M)

for m, match in enumerate(matches):
    for g, group_text in enumerate(match.groups()):
        print("###match {}, group {}:###".format(m, g))
        print(group_text, end="")

Я считаю, что хитрость заключается в использовании вложенных скобок и флага MULTILINE или M.

Результирующий match Объект (ы) будет иметь 3 группы, как определено в скобках:

  • группа 1: заголовок '.. code-block:'
  • группа 2: содержимое блока кода
  • группа 3: пустая группа в результате дополнительной круглой скобки.

Извлечь группу nиспользовать match.group(n), Обратите внимание, что индексация групп начинается с 1 и прохождение 0 или никакие аргументы не приведут ко всей совпадающей строке.

Другие вопросы по тегам