Получить повторяющийся контент с помощью регулярных выражений

У меня есть контент в формате:

text = """Pos no
...
... 25/gm
The Text to be 
...
excluded
Pos no
...
... 46 kg
The Text to be 
...
excluded
Pos no
...
... 46 xunit
End of My Text

Куда,Pos no... 25/gm - Это своего рода табличная структура, из которой я должен извлечь значения.

The Text to be ... excluded - Это имеет постоянный старт (скажем, The Text to be) но не определенный конец т.е. excluded может не присутствовать.

End of My Text - Этот текст всегда будет присутствовать.

Я хочу список только с табличным содержанием, т.е.

["Pos no
...
... 25/gm",
"Pos no
...
... 46 kg",
"Pos no
...
... 46 xunit"]

Вот моя попытка, но она не получает правильный список:

re.findall(r'(Pos no .+?)(?: |The Text to be|End of My Text)', text, re.DOTALL | re.M)

1 ответ

Решение

Вы можете использовать

re.findall(r'(?sm)(Pos no\r?\n.+?)[\r\n]+(?:The Text to be|End of My Text)', text)

Посмотреть демо Python

Обратите внимание, что Pos no не имеет места, но ваш шаблон требует этого. Кроме того, сопоставление правого контекста только в начале строки сделает сопоставление более безопасным.

Детали шаблона

  • (?sm) - re.DOTALL а также re.MULTILINE встроенные модификаторы (для более короткого кода)
  • (Pos no\r?\n.+?) - Группа 1 (что возвращается re.findall):
    • Pos no - буквальная подстрока
    • \r?\n - разрыв строки CRLF или LF
    • .+? - любые 1+ символов, как можно меньше, вплоть до самого левого вхождения последующих подшаблонов
  • [\r\n]+ - 1+ символов разрыва строки
  • (?:The Text to be|End of My Text) - любая из двух подстрок, The Text to be или же End of My Text,
Другие вопросы по тегам