正则表达式解析包装成xml的表

时间:2010-10-14 12:35:09

标签: python xml regex

假设我们有一张表:

Key|Val|Flag
01 |AAA| Y
02 |BBB| N
...

以这种方式包装成xml:

<Data>
  <R><F>Key</F><F>Val</F><F>Flag</F></R>
  <R><F>01</F><F>AAA</F><F>Y</F></R>
  <R><F>02</F><F>BBB</F><F>N</F></R>
  ...
</Data>

显然可以有更多的列和行。

现在我想使用单个正则表达式将XML解析回表。

我可以找到'<F>([\w\d]*)</F>'的所有字段,但我需要以某种方式按行分组。

我想过<R>(<F>([\w\d]*)</F>)*</R>,但是Python实现什么也找不到。

有人可以帮忙撰写正则表达式吗?

更新 问题的一些背景。

我知道大量的XML解析库,但不幸的是我的环境仅限于标准库。无论如何,感谢所有警告不要使用正则表达式进行XML解析的人。

我需要一些快速而肮脏的解决方案,因此我决定从正则表达式开始并稍后切换到解析。

到目前为止,我有代码:

...
row_p = r'<R>(.*?)</R>'
field_p = r'<F>(.*?)</F>'
table = ''

for row in re.finditer(row_p, xml):
    table += '|'.join(re.findall(field_p, row.group(1))) + '\n'

...

适用于小型数据集(约10,000行),但对于大于500'000行的表则无效。

也许我会做一些调查,为什么它会失败,但下一步我要采取 - 切换到一些标准的XML解析器。 ElementTree是第一位候选人。

4 个答案:

答案 0 :(得分:2)

强制性链接:

使用XML解析器。 lxml非常好,甚至提供(与其他XML相关的东西)XPath - 如果你对oneliner有一个迷信,我确信有一个XPath oneliner来提取这些元素;)

答案 1 :(得分:0)

如果这个问题用Perl标记,我可以为你发布一个解决方案+代码,但因为这是python。

无论如何,我建议你加载xml文件,并逐行读取。循环每一行直到文件末尾,并查找该行中的所有字段。据我所知,python中的匹配存储在一个数组中。你有它。希望我能用代码向您展示,但这只是主要想法:

load file
foreach line in <file>
    if regex.match('<F>([\w\d]*)</F>', line)
        print matches[1] . '|' . matches[2] . '|' . matches[3] . "\n"
end loop

免责声明:上面的代码只是一个划痕

哦顺便说一句,如果可能的话,请使用XML解析器。

答案 2 :(得分:0)

import libxml2

txt = '\n<Data>\n  <R><F>Key</F><F>Val</F><F>Flag</F></R>\n  <R><F>01</F><F>AAA</F><F>Y</F></R>\n  <R><F>02</F><F>BBB</F><F>N</F></R>\n</Data>\n'

rows = []
for elem in libxml2.parseDoc(txt):
    if elem.name == 'R':
        curRow = []
        rows.append(curRow)
    elif elem.name == 'F':
        curRow.append(elem.get_content())

返回:

rows = [['Key', 'Val', 'Flag'], ['01', 'AAA', 'Y'], ['02', 'BBB', 'N']] 

答案 3 :(得分:0)

  

lxml是一个Pythonic绑定   libxml2和libxslt库。它   它的独特之处在于它结合了   速度和功能完整性   这些库具有简单性   本机Python API,大多数兼容   但优于众所周知的   ElementTree API。