假设我们有一张表:
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是第一位候选人。
答案 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。