我正在尝试在Python中识别并存储文本文件中的数据。我上次使用Python已经有一段时间了,所以我可能对此有点生疏了。基本上,文本文件具有以下形式的数据
<THING1> \
var1 = 0 \#
var2 = "0.0 100.0 0.0" \#
var3 = "IDENTIFYING_WORD" \#
var4 = 2 \#
</THING1>
<THING2> \
# something similar
</THING2>
我已经能够识别出所需的文本文件部分,并将其存储为一个很长的字符串。假设文件名为data.txt,
with open('data.txt', 'r') as f:
content = f.read()
t1start = content.find('<THING1>')
t1end = content.find('</THING1>')
t1 = content[t1start:t1end]
f.close
从这里开始,我不知道该去哪里。我能够识别换行断点,并正在尝试使用它,但我确信它会起作用。例如,我可以说
i1 = t1.index('\n')
i2 = t1[i1+1:].index('\n')
line1 = t1[i1:i2]
但这并不是我想要的。
理想情况下,我希望数据在Python中存储为
var1 = 0
var2 = [0, 100, 0]
var3 = "IDENTIFYING_WORD"
var4 = 2
其中var1和var 4是int,var2是数组,var3是字符串。有人对此有什么想法吗?我试过在Stack上找别的地方,但什么也找不到。如果这个问题已经回答了,请告诉我正确的方向,我会把它记下来的。
谢谢!
发布于 2018-06-01 07:11:36
通常,当人们开始使用python编码时,他们会试图通过使用字符串操作或正则表达式等简单方法来解决这些典型的解析问题。当涉及到解决简单问题时,这两种方法都很好,但对于更复杂的问题,有更好的选择。
例如,对于这个特定的问题,没有真正的理由不尝试现有的许多可用的python parsing tools之一。为了证明这一点,让我们看看如何使用lark库来解决这个问题。
在pip安装了lark-parser
之后,请尝试以下代码片段:
import sys
import textwrap
from lark import Lark
if __name__ == "__main__":
content = textwrap.dedent(r"""
<THING1> \
var1 = 0 \#
var2 = "0.0 100.0 0.0" \#
var3 = "IDENTIFYING_WORD" \#
# something similar
var4 = 2 \#
</THING1>
<THING2> \
# something similar
var1 = 0 \#
</THING2>
""")
grammar = r"""
?start: block*
block: tag_start line* tag_end
tag_start: "<" NAME ">" "\\"
tag_end: "</" NAME ">"
line: assignment
| comment
assignment: lhs "=" rhs "\#"
comment: "#" NAME* NEWLINE
lhs: NAME
rhs: ESCAPED_STRING
| NAME
| NUMBER
%import common.NEWLINE
%import common.ESCAPED_STRING
%import common.CNAME -> NAME
%import common.NUMBER
%import common.WS
%ignore WS
"""
parser = Lark(grammar)
tree = parser.parse(content)
for block in tree.find_data("block"):
tag_name = list(block.find_data("tag_start"))[0].children[0]
print(tag_name.center(80, '-'))
for assignment in block.find_data("assignment"):
var_name = assignment.children[0].children[0]
value = assignment.children[1].children[0]
print(var_name, "=>", value)
你应该会得到这样的东西:
-------------------------------------THING1-------------------------------------
var1 => 0
var2 => "0.0 100.0 0.0"
var3 => "IDENTIFYING_WORD"
var4 => 2
-------------------------------------THING2-------------------------------------
var1 => 0
上面的示例并不打算是一个涵盖所有细节的完整示例,而只是说明使用现代解析库解决这些简单问题是多么容易的一个小示例。我将把它作为一个简单的练习,让您调整代码并尝试使用lark来满足您的需求。
发布于 2018-06-01 07:18:29
也许你可以像这样使用正则表达式:
import re
def get_value(y):
if 'var1' in y or 'var3' in y or 'var4' in y:
return_value = y.split('=')[1].strip()
try:
return int(return_value)
except ValueError:
return return_value
elif 'var2' in y:
return_value = y.split('=')[1].strip().split(" ")
return [float(i.replace('"','')) for i in return_value]
string = """
<THING1> \
var1 = 0 \#
var2 = "0.0 100.0 0.0" \#
var3 = "IDENTIFYING_WORD" \#
var4 = 2 \#
</THING1>
<THING2> \
var1 = 5 \#
var2 = "0.0 100.0 0.0" \#
var3 = "IDENTIFYING_WORD" \#
var4 = 7 \#
</THING2>
"""
pat = re.compile(r'<THING\d>(.*?)</THING\d>')
x = re.findall(pat, string.replace('\n',''))
mainlist = [['var1','var2','var3','var4']]
for i in x:
mylist = []
for j in i.split(r'\#'):
if j.strip() != '':
mylist.append(get_value(j))
mainlist.append(mylist)
print(mainlist)
结果:
[
['var1', 'var2', 'var3', 'var4'],
[0, [0.0, 100.0, 0.0], '"IDENTIFYING_WORD"', 2],
[5, [0.0, 100.0, 0.0], '"IDENTIFYING_WORD"', 7]
]
https://stackoverflow.com/questions/50633385
复制相似问题