RegEx для захвата части строки - PullRequest
3 голосов
/ 26 мая 2019

Я пытаюсь получить заголовки Markdown верхнего уровня (т. Е. Заголовки, начинающиеся с одного хеша - # Введение) в документе .md с библиотекой Python и не могу понять, насколько я понимаю.

Вот код, который я пытаюсь выполнить:

import re

pattern = r"(# .+?\\n)"

text = r"# Title\n## Chapter\n### sub-chapter#### What a lovely day.\n"

header = re.search(pattern, text)
print(header.string)

Результат от print(header.string):

# Title\n## Chapter\n### sub-chapter#### What a lovely day.\n тогда как я хочу только # Title\n

Этот пример на regex101 говорит, что он должен работать, но я не могу понять, почему это не так. https://regex101.com/r/u4ZIE0/9

Ответы [ 2 ]

2 голосов
/ 26 мая 2019

Вы получите этот результат, потому что вы используете header.string, который вызывает .string для объекта Match * , который вернет вам строку, переданную в match() или поиск ().

В строке уже есть новые строки:

text = r"# Title\n## Chapter\n### sub-chapter#### What a lovely day.\n"

Так что, если вы используете свой шаблон (обратите внимание, что он также будет соответствовать новой строке), вы можете обновить свой код до:

import re

pattern = r"(# .+?\\n)"
text = r"# Title\n## Chapter\n### sub-chapter#### What a lovely day.\n"
header = re.search(pattern, text)
print(header.group())

Демо Python

Обратите внимание, что re.search ищет первое местоположение, где регулярное выражение производит совпадение.

Другим вариантом, соответствующим вашему значению, может быть совпадение с начала строки #, за которым следует пробел, а затем любой символ, кроме новой строки, до конца строки:

^# .*$

Например:

import re

pattern = r"^# .*$"
text = "# Title\n## Chapter\n### sub-chapter#### What a lovely day.\n"
header = re.search(pattern, text, re.M)
print(header.group())

Python demo

Если после этого не может быть больше #, вы также можете использовать отрицательный класс символов , чтобы не совпадать с # или символом новой строки:

^# [^#\n\r]+$
1 голос
/ 26 мая 2019

Я предполагаю, что мы хотим извлечь # Title\n, и в этом случае ваше выражение работает нормально с небольшой модификацией:

(# .+?\\n)(.+)

DEMO

Test

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"(# .+?\\n)(.+)"

test_str = "# Title\\n## Chapter\\n### sub-chapter#### The Bar\\nIt was a fall day.\\n"

subst = "\\1"

# You can manually specify the number of replacements by changing the 4th argument
result = re.sub(regex, subst, test_str, 1)

if result:
    print (result)

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...