Как я могу сопоставить блок кода 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.

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

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

Klaus D. 31.10.2018 13:08

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

Steve Piercy 31.10.2018 13:33

@KlausD. Есть ли у вас какие-либо рекомендации по поводу парсеров, в которые я могу заглянуть?

Vuyisile Ndlovu 31.10.2018 19:34
eli.thegreenplace.net/2017/…
Klaus D. 31.10.2018 21:58

Спасибо за ссылку.

Vuyisile Ndlovu 01.11.2018 10:05
0
5
246
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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 или отсутствие аргументов приведет к получению всей совпадающей строки.

Спасибо тебе за это! Оно работает. Есть ли способ выбрать тот же текст и нет включить директиву code-block:: python в объект соответствия?

Vuyisile Ndlovu 31.10.2018 18:55

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