解析要存储到类对象和属性中的文本文件

2024-10-04 01:23:12 发布

您现在位置:Python中文网/ 问答频道 /正文

两部分问题。如何解析文本并另存为类对象/属性,以及以特定格式重写类中文本的最佳方法。在

我想通过一个文本和一个类来解析一个文本和一个类的属性。将涉及到几个类(多边形、空间、分区、系统、时间表)。在原始文件中,每个“对象”及其“属性”都用“..”分隔。下面是一个例子。在

"Office PSZ" = SYSTEM
    TYPE             = PSZ
    HEAT-SOURCE      = FURNACE
    FAN-SCHEDULE     = "HVAC Yr Schedule"
    COOLING-EIR      = 0.233207
    ..

我想阅读本文并将其存储到类对象中。所以“Office PSZ”应该是hvac系统还是系统类,还没有决定系统”将是一个类变量。对于本例(“Office PSZ”),自身类型会是PSZ。自热-来源等于熔炉等

我想根据它们的属性来操纵这些对象。但最终的结果是将所有被操作的数据写回原始格式的文本文件中。此实例的最终结果可能是。在

^{pr2}$

有没有办法打印属性名/标题(idk怎么称呼它)?因为属性名(即TYPE、HEAT-SOURCE)来自原始文件,因此不必手动预测与每个类相关联的所有属性会更容易。在

我想我可以在“=”的左边创建一个包含所有值的数组,为右边的值创建另一个数组,并在编写/格式化一个新的文本文件时循环这些值。但我不确定这是不是个好办法。在

我还是个业余爱好者,所以我可能做得太过火了,但是有什么建议可以让我继续下去吗?在


Tags: 文件对象方法文本source属性系统格式
1条回答
网友
1楼 · 发布于 2024-10-04 01:23:12

Pyparsing使编写像这样的数据的自定义解析器变得容易,并返回给用户 pyparsing数据结构中解析的数据调用ParseResults。ParseResults为您提供 通过位置(如列表)、键(如dict)或for访问已解析的值 按属性(如对象)作为Python标识符的名称。在

我已经简化了对数据的解析,几乎只需占用key = value行 并使用键串作为键建立一个结构。“…”线很好用 作为每个对象的终止符。在

一个简单的BNF可能看起来像:

object ::= attribute+ end
attribute ::= key '=' value
key ::= word composed of letters 'A'..'Z' and '-', starting with 'A'..'Z', 
          or a quoted string
value ::= value_string | value_number | value_word
value_word ::= a string of non-whitespace characters
value_string ::= a string of any characters in '"' quotes
value_number ::= an integer or float numeric value
end ::= '..'

为了实现pyparsing解析器,我们自下而上定义pyparsing子表达式。 然后我们使用Python“+”和“|”运算符将较低级别的表达式组装到较高级别 一个:

^{pr2}$

pyparsing包括一些用于引用字符串和数字的预定义表达式; 数字将自动转换为整数或浮点。在

value_number = pp.pyparsing_common.number
value_string = pp.quotedString
value_word = pp.Word(pp.printables)
value = value_string | value_number | value_word

对于属性键,我们将对Word使用双参数形式。第一个 参数是允许的前导字符字符串,第二个参数是 允许的正文字符字符串。如果我们只写'Word(alphas+'-'),那么 我们的解析器将接受“-”作为合法密钥。在

key = pp.Word(pp.alphas, pp.alphas + '-') | pp.quotedString

属性定义只是一个键、一个“=”号和一个值

attribute = key + EQ + value

最后,我们将使用pyparsing的一些更复杂的特性。最简单的形式 只会是“一页或多页(属性)+END”,但这只会返回一个 一堆没有结构的已解析标记。Group类构造封闭表达式 这样他们的结果将作为子列表返回。我们将捕捉每个属性 它自己的子列表使用组。Dict将对结果应用一些命名,使用 每个键表达式中的文本作为该组的键。最后,整个系列 属性的属性将再次分组,这次表示 单个对象:

object_defn = pp.Group(pp.Dict(pp.OneOrMore(pp.Group(attribute)))) + END

要使用此表达式,我们将把解析器定义为:

parser = pp.OneOrMore(object_defn)

并使用以下方法解析示例字符串:

objs = parser.parseString(sample)

我们返回的objs变量将是一个pyparsing ParseResults,其工作原理如下 分组对象属性的列表。我们可以将解析后的属性作为列表查看 使用asList()的列表:

for obj in objs:
    print(obj.asList())

[['"Office PSZ"', 'SYSTEM'], ['TYPE', 'PSZ'], ['HEAT-SOURCE', 'FURNACE'], 
 ['FAN-SCHEDULE', '"HVAC Yr Schedule"'], ['COOLING-EIR', 0.233207]]

如果我们没有使用Dict类,这将是我们能得到的全部,但是由于我们 如果使用Dict,我们也可以将属性视为Python Dict:

for obj in objs:
    print(obj.asDict())

{'COOLING-EIR': 0.233207, '"Office PSZ"': 'SYSTEM', 'TYPE': 'PSZ', 
 'FAN-SCHEDULE': '"HVAC Yr Schedule"', 'HEAT-SOURCE': 'FURNACE'}

如果命名字段作为Python标识符工作,我们甚至可以按名称访问它们。在你的 示例,“TYPE”是唯一合法的标识符,因此您可以在这里看到如何打印它。在那里 也是一个dump()方法,它将以列表形式给出结果,后跟一个 已定义密钥对的缩进列表。(我还演示了如何使用list和dict 直接在ParseResults对象上键入access,而不必转换为list 或dict类型):

for obj in objs:
    print(obj[0])
    print(obj['FAN-SCHEDULE'])
    print(obj.TYPE)
    print(obj.dump())

['"Office PSZ"', 'SYSTEM']
"HVAC Yr Schedule"
PSZ
[['"Office PSZ"', 'SYSTEM'], ['TYPE', 'PSZ'], ['HEAT-SOURCE', 'FURNACE'], 
 ['FAN-SCHEDULE', '"HVAC Yr Schedule"'], ['COOLING-EIR', 0.233207]]
- "Office PSZ": 'SYSTEM'
- COOLING-EIR: 0.233207
- FAN-SCHEDULE: '"HVAC Yr Schedule"'
- HEAT-SOURCE: 'FURNACE'
- TYPE: 'PSZ'

下面是完整的解析器代码,供您使用:

import pyparsing as pp

END = pp.Suppress("..")
EQ = pp.Suppress('=')

value_number = pp.pyparsing_common.number
value_string = pp.quotedString
value_word = pp.Word(pp.printables)
value = value_string | value_number | value_word

key = pp.Word(pp.alphas, pp.alphas+"-") | pp.quotedString

attribute = key + EQ + value
object_defn = pp.Group(pp.Dict(pp.OneOrMore(pp.Group(attribute)))) + END

parser = pp.OneOrMore(object_defn)
objs = parser.parseString(sample)

for obj in objs:
    print(obj.asList())

for obj in objs:
    print(obj.asDict())

for obj in objs:
    print(obj[0])
    print(obj['FAN-SCHEDULE'])
    print(obj.TYPE)
    print(obj.dump())

相关问题 更多 >