Регулярное выражение Python, пропускающее первые несколько символов?
-
06-07-2019 - |
Вопрос
Привет, у меня есть довольно простой вопрос о регулярных выражениях.Я хочу просто вернуть текст внутри (и включая) тегов body, и я знаю, что следующее неверно, потому что оно также будет соответствовать всем символам перед открывающим тегом body.Мне было интересно, как бы вы отнеслись к тому, чтобы пропустить их?
x = re.match('(.*<body).*?(</body>)', fileString)
Спасибо!
Решение
Вот некоторый пример кода, который использует регулярное выражение для поиска всего текста между <body>...</body>
Теги.Хотя это демонстрирует некоторые особенности модуля re python, обратите внимание, что Прекрасный Суп модуль очень прост в использовании и является лучшим инструментом для использования, если вы планируете анализировать HTML или XML.(Смотрите ниже пример того, как вы могли бы проанализировать это с помощью BeautifulSoup.)
#!/usr/bin/env python
import re
# Here we have a string with a multiline <body>...</body>
fileString='''baz<body>foo
baby foo
baby foo
baby foo
</body><body>bar</body>'''
# re.DOTALL tells re that '.' should match any character, including newlines.
x = re.search('(<body>.*?</body>)', fileString, re.DOTALL)
for match in x.groups():
print(match)
# <body>foo
# baby foo
# baby foo
# baby foo
# </body>
Если вы хотите собрать все совпадения, вы могли бы использовать re.findall:
print(re.findall('(<body>.*?</body>)', fileString, re.DOTALL))
# ['<body>foo\nbaby foo\nbaby foo\nbaby foo\n</body>', '<body>bar</body>']
и если вы планируете использовать этот шаблон более одного раза, вы можете предварительно скомпилировать его:
pat=re.compile('(<body>.*?</body>)', re.DOTALL)
print(pat.findall(fileString))
# ['<body>foo\nbaby foo\nbaby foo\nbaby foo\n</body>', '<body>bar</body>']
И вот как вы могли бы сделать это с помощью BeautifulSoup:
#!/usr/bin/env python
from BeautifulSoup import BeautifulSoup
fileString='''baz<body>foo
baby foo
baby foo
baby foo
</body><body>bar</body>'''
soup = BeautifulSoup(fileString)
print(soup.body)
# <body>foo
# baby foo
# baby foo
# baby foo
# </body>
print(soup.findAll('body'))
# [<body>foo
# baby foo
# baby foo
# baby foo
# </body>, <body>bar</body>]
Другие советы
Я не знаю Python, но вот краткий пример, собранный вместе с использованием Прекрасный Суп, который, как я часто вижу, рекомендуется для синтаксического анализа HTML на Python.
import BeautifulSoup
soup = BeautifulSoup(fileString)
bodyTag = soup.html.body.string
Это позволит (теоретически) справиться со всеми сложностями HTML, что очень сложно с ответами на основе чистых регулярных выражений, потому что это не то, для чего было разработано регулярное выражение.
Вы не можете анализировать HTML с помощью регулярного выражения.HTML не является обычным языком.Вместо этого используйте анализатор HTML, такой как lxml.
x = re.match('.*(<body>.*?</body>)', fileString)
Рассмотрим minidom для синтаксического анализа HTML.
x = re.search('(<body>.*</body>)', fileString)
x.group(1)
Меньше ввода текста, чем совпадающих ответов
Содержит ли ваша файловая строка несколько строк?В этом случае вам может потребоваться указать это или явно пропустить строки:
x = re.match(r"(?:.|\n)*(<body>(?:.|\n)*</body>)", fileString)
или, проще говоря, с помощью модуля re:
x = re.match(r".*(<body>.*</body>)", fileString, re.DOTALL)
x.groups()[0]
должна содержать вашу строку, если x не равно None.