如何在Python3.x中识别和存储格式化文本文件中的变量和数据?

2024-10-06 12:07:11 发布

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

我试图用Python识别并存储文本文件中的数据。我上次使用Python已经有一段时间了,所以我可能对它生疏了。从本质上说,文本文件具有以下格式的数据

<THING1> \ 
 var1         =  0        \#
   var2      = "0.0 100.0 0.0"          \#
var3     = "IDENTIFYING_WORD"      \#
var4      = 2                 \#
</THING1>

<THING2> \
 # something similar
</THING2>

我已经能够识别出我需要的文本文件部分,并将其存储为一个大的长字符串。假设文件被调用数据.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]

但这不是我想要的。你知道吗

理想情况下,我希望数据以

var1 = 0
var2 = [0, 100, 0]
var3 = "IDENTIFYING_WORD"
var4 = 2

其中var1和var4是int,var2是数组,var3是字符串。有人对此有想法吗?我试过在堆栈的其他地方找,但什么也找不到。如果这个问题已经得到了回答,请告诉我正确的方向,我会把这个拿下来。你知道吗

谢谢!你知道吗


Tags: 数据字符串txtcontentwordt1文本文件i1
2条回答

也许你可以这样使用正则表达式:

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]
]

通常,当人们开始用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来满足您的需要。你知道吗

相关问题 更多 >