在两个String-Regex&之间提取递归的多行数据。 Python& XML

时间:2016-05-26 08:23:31

标签: python regex xml parsing

我有一个巨大的XML文件,我需要从中获取特定条目的数据。文件结构是:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE stuff>
<?xml-stylesheet href="file:///usr/local/test.xsl" type="text/xsl"?>
<!-- 127.0.0.1 -->
<opentag>
<tag1><XXXX YYYY VVV SSS></tag1>
<tag2>
<test>aaa_string_bbb_ccc</test>
</tag2>  
<debugging level="0"/>
</opentag>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE >
<?xml-stylesheet href="file:///usr/local/test.xsl" type="text/xsl"?>
<!-- 192.168.10.1 -->
<opentag>
<tag1><DDD FFF BBB></tag1>
<tag2>
<test>zzz_number_yyy_xxxx</test>
</tag2>
<debugging level="0"/>
</opentag>

在我的XML中,我有很多这样的条目。 我必须实现的是提取某些条目的所有行(完整记录)。 我需要创建不同的xml文件,每次在文本之间找到一个文件 <?xml version="1.0" encoding="UTF-8"?>  到下一个 </opentag>

在这种情况下,我想有两个不同的文件名的xml文件。例如:

1 - &gt; 127.0.0.1.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE stuff>
<?xml-stylesheet href="file:///usr/local/test.xsl" type="text/xsl"?>
<!-- 127.0.0.1 -->
<opentag>
<tag1><XXXX YYYY VVV SSS></tag1>
<tag2>
<test>aaa_string_bbb_ccc</test>
</tag2>
<debugging level="0"/>
</opentag>

和第二个:

2 - &gt; 192.168.10.1.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE >
<?xml-stylesheet href="file:///usr/local/test.xsl" type="text/xsl"?>
<!-- 192.168.10.1 --> 
<opentag>
<tag1><DDD FFF BBB></tag1>
<tag2>
<test>zzz_number_yyy_xxxx</test>
</tag2>
<debugging level="0"/>
</opentag>

对于特定条目,可以执行此类记录提取的REGEX是什么? 有没有更多的pythonic方法来实现这一目标? 我很感激你的帮助。

AS

2 个答案:

答案 0 :(得分:0)

假设所有文件的格式相同,<!-- 127.10.10.1 -->实际上在第一个文件中,您可以使用 itertools.groupby 对这些部分进行分组:

from itertools import groupby

with open("your_file") as f:
   grps = groupby(f, key=lambda x: x.strip().startswith('<?xml version>'))
   for k, v in grps:
      if k:
          lines = list(v) + list(next(grps)[1])
          with open("{}".format(lines[2]), "w") as out:
              out.writelines( lines)

您的示例数据为您提供了您想要的内容。

答案 1 :(得分:0)

不要使用正则表达式。而是查看ElementTree模块。有了这个,你可以迭代所有的opentag,然后将每个opentags写入一个不同的文件。这比使用正则表达更加pythonic(&#39; 不要重新发明轮子&#39;)。

如果你必须使用正则表达式,你可以这样做:

(<\?xml version="1\.0" encoding="UTF-8"\?>.+?<\/opentag>)

确保传递's'修饰符,以便'.'匹配换行符。

这是最终解决方案:

pattern = re.compile('<\?xml version="1\.0" encoding="UTF-8"\?>.+?<\/nmaprun>', re.DOTALL)
result= re.findall(pattern,data)
for item in result:
            print item