Как использовать регулярные выражения для поиска значений атрибутов в кавычках в файле OPML (XML)
Я ищу в файле OPML, который выглядит примерно так. Я хочу вытащить наброски текста и xmlUrl.
<outline text="lol">
<outline text="Discourse on the Otter" xmlUrl="http://discourseontheotter.tumblr.com/rss" htmlUrl="http://discourseontheotter.tumblr.com/"/>
<outline text="fedoras of okc" xmlUrl="http://fedorasofokc.tumblr.com/rss" htmlUrl="http://fedorasofokc.tumblr.com/"/>
</outline>
Моя функция:
import re
rssName = 'outline text="(.*?)"'
rssUrl = 'xmlUrl="(.*?)"'
def rssSearch():
doc = open('ttrss.txt')
for line in doc:
if "xmlUrl" in line:
mName = re.search(rssName, line)
mUrl = re.search(rssUrl, line)
if mName is not None:
print mName.group()
print mUrl.group()
Однако возвращаемые значения выглядят так:
outline text="fedoras of okc"
xmlUrl="http://fedorasofokc.tumblr.com/rss"
Каково правильное выражение регулярного выражения для rssName и rssUrl, чтобы я возвращал только строку между кавычками?
2 ответа
Не используйте регулярные выражения для разбора XML. Код грязный, и слишком много вещей может пойти не так.
Например, что если ваш провайдер OPML переформатирует свой вывод следующим образом:
<outline text="lol">
<outline
htmlUrl="http://discourseontheotter.tumblr.com/"
xmlUrl="http://discourseontheotter.tumblr.com/rss"
text="Discourse on the Otter"
/>
<outline
htmlUrl="http://fedorasofokc.tumblr.com/"
xmlUrl="http://fedorasofokc.tumblr.com/rss"
text="fedoras of okc"
/>
</outline>
Это совершенно верно, и это означает то же самое. Но линейно-ориентированный поиск и регулярные выражения, такие как 'outline text="(.*?)"'
сломает.
Вместо этого используйте синтаксический анализатор XML. Ваш код будет чище, проще и надежнее:
import xml.etree.cElementTree as ET
root = ET.parse('ttrss.txt').getroot()
for outline in root.iter('outline'):
text = outline.get('text')
xmlUrl = outline.get('xmlUrl')
if text and xmlUrl:
print text
print xmlUrl
Это относится и к вашему фрагменту OPML, и к аналогичным файлам OPML, которые я нашел в Интернете, например, к списку политологов. И это очень просто, ничего сложного в этом нет. (Я не хвастаюсь, это просто преимущество, которое вы получаете от использования парсера XML вместо регулярных выражений.)
Пытаться
print mName.group(1)
print mUrl.group(1)
http://docs.python.org/2/library/re.html
Если аргумент groupN равен нулю, соответствующим возвращаемым значением является вся совпадающая строка; если он находится в включающем диапазоне [1..99], это строка, соответствующая соответствующей группе в скобках.
или же
rssName = 'outline text="(?P<text>.*?)"'
а потом
print mName.group('text')