Question

I have the following Python regex:

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)

for the following text:

<?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>

The groups that are being returned are:
(1) Desired Group #1
(2) Undesired Group #2
(3) Undesired Group #3
(4) Undesired Group #4

Why is this happening? Since I'm getting Desired Group #1 and using non-greedy .+? with flags=re.DOTALL, I would expect that it would not skip over any of my Desired Groups 2-4.

Thanks in advance.


UPDATE:

Ended up using xml.etree.ElementTree as follows:

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")  

Found the following link useful for NCBI BLAST specific XML parsing examples: http://www.dalkescientific.com/writings/NBN/elementtree.html

Was it helpful?

Solution

Hmmm, XML and a Regex. Looks like fun.

How about you use a built-in Python XML library, like libxml2 or 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

Seriously, you'll save yourself a lot of headaches. Regex is not meant for XML parsing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top