用python解析结构化文本文件
我需要用Python解析与下面类似的文本文件,构建数据的层次对象结构,然后对其进行处理。这与我们使用xml.etree.ElementTree和其他xml解析器所做的非常相似 但是,这些文件的语法不是XML,我想知道实现这样一个解析器的最佳方法是什么:如果试图对一个XML解析器(哪一个)进行子类化,并自定义其标记识别行为,那么编写自定义解析器,等等用python解析结构化文本文件,python,xml,parsing,Python,Xml,Parsing,我需要用Python解析与下面类似的文本文件,构建数据的层次对象结构,然后对其进行处理。这与我们使用xml.etree.ElementTree和其他xml解析器所做的非常相似 但是,这些文件的语法不是XML,我想知道实现这样一个解析器的最佳方法是什么:如果试图对一个XML解析器(哪一个)进行子类化,并自定义其标记识别行为,那么编写自定义解析器,等等 {NETLIST topblock {VERSION 2 0 0} {CELL topblock {PORT gearshift_h vp
{NETLIST topblock
{VERSION 2 0 0}
{CELL topblock
{PORT gearshift_h vpsf vphreg pwron_h vinp vref_out vcntrl_out gd meas_vref
vb vout meas_vcntrl reset_h vinm }
{INST XI21/Mdummy1=pch_18_mac {TYPE MOS} {PROP n="sctg_inv1x/pch_18_mac" Length=0.152 NFIN=8 }
{PIN vpsf=SRC gs_h=DRN vpsf=GATE vpsf=BULK }}
{INST XI21/Mdummy2=nch_18_mac {TYPE MOS} {PROP n="sctg_inv1x/nch_18_mac" Length=0.152 NFIN=5 }
{PIN gs_h=SRC gd=DRN gd=GATE gd=BULK }}
{INST XI20/Mdummy1=pch_18_mac {TYPE MOS} {PROP n="sctg_inv1x/pch_18_mac" Length=0.152 NFIN=8 }
{PIN vpsf=SRC gs_hn=DRN vpsf=GATE vpsf=BULK }}
{INST XI20/Mdummy2=nch_18_mac {TYPE MOS} {PROP n="sctg_inv1x/nch_18_mac" Length=0.152 NFIN=5 }
{PIN gs_hn=SRC gd=DRN gd=GATE gd=BULK }}
{INST XI19/Mdummy1=pch_18_mac {TYPE MOS} {PROP n="sctg_inv1x/pch_18_mac" Length=0.152 NFIN=8 }
{PIN vpsf=SRC net514=DRN vpsf=GATE vpsf=BULK }}
{INST XI19/Mdummy2=nch_18_mac {TYPE MOS} {PROP n="sctg_inv1x/nch_18_mac" Length=0.152 NFIN=5 }
{PIN net514=SRC gd=DRN gd=GATE gd=BULK }}
{INST XI21/MN0=nch_18_mac {TYPE MOS} {PROP n="sctg_inv1x/nch_18_mac" Length=0.152 NFIN=5 }
{PIN gd=SRC gs_h=DRN gs_hn=GATE gd=BULK }}
{INST XI21/MP0=pch_18_mac {TYPE MOS} {PROP n="sctg_inv1x/pch_18_mac" Length=0.152 NFIN=8 }
{PIN vpsf=SRC gs_h=DRN gs_hn=GATE vpsf=BULK }}
{INST XI20/MN0=nch_18_mac {TYPE MOS} {PROP n="sctg_inv1x/nch_18_mac" Length=0.152 NFIN=5 }
...
}
}
首先,您应该检查是否已有可用于文件格式的解析器。显然有:
如果您找不到任何合适的工具,您可以使用大量可用库中的一个来构建解析器,例如pyparsing。子类化XML解析器似乎不是一个好主意。其他人在评论中说的:使用现有的解析器。如果不存在,请使用自己的解析器库。在这里,例如:
此文本文件不是Verilog网络列表。它是IC验证器EDA工具的网络列表输出之一,在我看来,它是一种自定义的网络列表格式,至少这不是通常的SPICE、LEF或EDIF。也许这是Verilog格式的扩展。在这种情况下,它可能与Verilog的格式非常相似,从而使Python库的扩展变得足够简单。否则,您可以尝试使用pyparsing或其他方法构建自己的解析器。如果格式足够简单,那么string.split和正则表达式可能就是您所需要的全部…这不是Verilog的扩展,Verilog完全不同。然而,这似乎是有希望的。谢谢我说过,有很多Python库可供解析,请参见这里。你可能会发现一些比pyparsing更让你喜欢的东西,但它应该没问题。但实际上,确保你不会破门而入。也许有一个开源软件可以解析这种格式。或者该工具可以选择生成一个XML而不是这个。无论如何,将XML解析器子类化以解析不同于XML的格式不是一个好主意。这是一个非常好的实践。非常感谢。非常好,非常好!
from pprint import pprint
from parcon import (Forward, SignificantLiteral, Word, alphanum_chars, Exact,
ZeroOrMore, CharNotIn, concat, OneOrMore)
block = Forward()
hyphen = SignificantLiteral('"')
word = Word(alphanum_chars + '/_.)')
value = word | Exact(hyphen + ZeroOrMore(CharNotIn('"')) + hyphen)[concat]
pair = word + '=' + value
flag = word
attribute = pair | flag | block
head = word
body = ZeroOrMore(attribute)
block << '{' + head + body + '}'
blocks = OneOrMore(block)
with open('<your file name>.txt') as infile:
pprint(blocks.parse_string(infile.read()))
[('NETLIST',
['topblock',
('VERSION', ['2', '0', '0']),
('CELL',
['topblock',
('PORT',
['gearshift_h',
'vpsf',
'vphreg',
'pwron_h',
'vinp',
'vref_out',
'vcntrl_out',
'gd',
'meas_vref',
'vb',
'vout',
'meas_vcntrl',
'reset_h',
'vinm']),
('INST',
[('XI21/Mdummy1', 'pch_18_mac'),
('TYPE', ['MOS']),
('PROP',
[('n', '"sctg_inv1x/pch_18_mac"'),
('Length', '0.152'),
('NFIN', '8')]),
('PIN',
[('vpsf', 'SRC'),
('gs_h', 'DRN'),
('vpsf', 'GATE'),
('vpsf', 'BULK')])]),
('INST',
...