Python regex слишком жадный, пропускает первое вхождение в XML - PullRequest
1 голос
/ 04 марта 2012

У меня есть следующее регулярное выражение Python:

xml_parse = re.search(r'^.+?<Hit_accession>(\w+?)</Hit_accession>.+?<Hsp_qseq>(\w+?)</Hsp_qseq>\s+?<Hsp_hseq>(\w+?)</Hsp_hseq>\s+?<Hsp_midline>(.+?)</Hsp_midline>',string,flags=re.DOTALL)

для следующего текста:

<?xml version="1.0"?>
 <Hit_accession> Desired Group #1 </Hit_accession>
<Hsp>
 <Hsp_qseq> Desired Group # 2 </Hsp_qseq>
 <Hsp_hseq> Desired Group # 3 </Hsp_hseq>
 <Hsp_midline> Desired Group # 4 </Hsp_midline>
</Hsp>

... way later in the XML string

 <Hit_accession> Undesired Group #1 </Hit_accession>
<Hsp>
 <Hsp_qseq> Undesired Group # 2 </Hsp_qseq>
 <Hsp_hseq> Undesired Group # 3 </Hsp_hseq>
 <Hsp_midline> Undesired Group # 4 </Hsp_midline>
</Hsp>

Возвращаемые группы:
(1) Желаемая группа #1
(2) нежелательная группа № 2
(3) нежелательная группа № 3
(4) нежелательная группа № 4

Почему это происходит?Так как я получаю Desired Group # 1 и использую не жадный. +?с flags = re.DOTALL, я ожидал бы, что он не пропустит ни одну из моих Желаемых групп 2-4.

Заранее спасибо.


ОБНОВЛЕНИЕ:

Завершено использованием xml.etree.ElementTree следующим образом:

tree = xml.etree.ElementTree.fromstring(string)
iteration = tree.find("BlastOutput_iterations/Iteration")
hits = iteration.findall("Iteration_hits/Hit")
topHit = hits[0]
accessionNCBI = topHit.findtext("Hit_accession")  

Найдена следующая ссылка, полезная для примеров анализа XML для NCBI BLAST: http://www.dalkescientific.com/writings/NBN/elementtree.html

1 Ответ

5 голосов
/ 04 марта 2012

Хммм, XML и регулярное выражение. Похоже, весело.

Как насчет использования встроенной библиотеки Python XML, такой как libxml2 или ElementTree?

from xml.etree.ElementTree import ElementTree
doc = ElementTree(file='myfile.xml')

for e in doc.findall('/Hit_accession'):
    print e.get('Hsp_qseq').text

Серьезно, вы избавите себя от многих головных болей. Regex не предназначен для парсинга XML.

...