У меня есть файл с множеством xml-подобных элементов, таких как:
<document docid=1>
Preliminary Report-International Algebraic Language
Perlis, A. J. & Samelson,K.
CACM December, 1958
</document>
Мне нужно разобрать докид и текст. Какое подходящее регулярное выражение для этого?
Я пробовал это, но он не работает:
collectionText = open('documents.txt').read()
docsPattern = r'<document docid=(\d+)>(.)*</document>'
docTuples = re.findall(docsPattern, collectionText)
EDIT: Я изменил шаблон следующим образом:
<document docid=(\d+)>(.*)</document>
Это соответствует всему документу, к сожалению, не отдельным элементам документа.
EDIT2: Правильная реализация от ответа Ахмада и Акорна:
collectionText = open('documents.txt').read()
docsPattern = r'<document docid=(\d+)>(.*?)</document>'
docTuples = re.findall(docsPattern, collectionText, re.DOTALL)
Ваш шаблон жадный, поэтому, если у вас несколько элементов <document>
он будет соответствовать всем им.
Вы можете сделать это не жадным, используя .*?
, что означает "совместить ноль или больше символов, как можно меньше". Обновленный шаблон:
<document docid=(\d+)>(.*?)</document>
Вы должны использовать DOTALL
вариант с регулярным выражением так, что он будет соответствовать на несколько строк (по умолчанию .
Не будет соответствовать новым строке символов).
Также обратите внимание на комментарии относительно жадности в ответе Ахмада.
import re
text = '''<document docid=1>
Preliminary Report-International Algebraic Language
Perlis, A. J. & Samelson,K.
CACM December, 1958
</document>'''
pattern = r'<document docid=(\d+)>(.*?)</document>'
print re.findall(pattern, text, re.DOTALL)
В общем случае регулярные выражения не подходят для синтаксического анализа XML/HTML.
Видеть:
RegEx сопоставляет открытые теги, за исключением автономных тегов XHTML, и http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html
Вы хотите использовать парсер, например, lxml
.
DOTALL
Кажется, работает для.net "xml-like" структуры просто FYI...
<([^<>]+)>([^<>]+)<(\/[^<>]+)>