【问题标题】:Python get multiline value from properties filePython从属性文件中获取多行值
【发布时间】:2022-01-22 00:47:12
【问题描述】:

我有包含多行的属性文件和超过 1 行的一些值。像这样的:

first.key=\
        Right,\
        Side,\
        Value
second.key=Second value
third.key=Third value

我想获取每个键的值。 我无法预处理文件,因此无法用三引号或其他任何内容括起来。 因此,例如,如果我想将文件中的每个键和值放在一个列表中,例如:

for line in file:
    split = line.split('=')

然后获取key和value

key = split[0]
value = split[1]

print(key) -> first.key
print(value) -> \Right,\Side,\Value


for line in file:
    while line.endswith('\\'):
        line += next(file)

will give me TypeError: 'list' object is not an iterator

请记住,属性文件的每一行都是列表中的项目。 我能够为每一行提取键和值,但我正在努力如何使用多行值来做到这一点。如果上一行.endswith('\'),我可能应该将下一行附加到上一行,但我无法弄清楚。 编辑。 ['multiline.key=值的第一行\', '值的第二行\', '值的第三行\', '值的第四行\', '值的第五行\', 'another.key=某个值', 'some.key= 另一个值'] 我知道如何处理 'another.key=某个值', 'some.key=另一个值'

我想不通的是如何提取为单个值:

First line of the value\\', 'Second line of the value\\', 'Third 
line of the value\\', 'Fourth line of the value\\', 'Fifth line of 
the value\\'

对于 多行键

文件如下所示:

multiline.key=First line of the value\
Second line of the value\
Third line of the value\
Fourth line of the value\
Fifth line of the value\
another.key=Some value
some.key=Another value

预期结果:

1st key=multiline.key
1st value=First line of the value\Second line of the value\Third 
line of the value\Fourth line of the value\Fifth line of the value\

2nd key=another.key
2nd value=Some value

3rd key=some.key
3rd value=Another value

【问题讨论】:

  • 这能回答你的问题吗? parsing .properties file in Python
  • 对于显示的文件,您的预期结果究竟是什么样的?目前尚不清楚您想要什么的示例,和/或您(错误地)得到的示例。
  • 我想获取文件中的每个值,甚至是多行上的值。缺少哪些信息,我可以改进它吗?
  • 在你最后显示的文件之后,显示(不仅仅是描述)你想要的输出。我认为这是三个字符串的列表?还是一个字典,其值是那些字符串?
  • 谢谢。列表的使用似乎很奇怪,但至少它相当清楚你想要什么,如果不是为什么。你熟悉 Python dictionaries 吗?这将是表示键和值的更自然的选择。

标签: python extract key-value multiline properties-file


【解决方案1】:

属性文件与 INI 文件完全相同。

您可以使用configparser 和假部分来轻松解析它:

data = r"""first.key=\
        Right,\
        Side,\
        Value
second.key=Second value
third.key=Third value"""

import configparser

def read_properties(data: str):
    config = configparser.ConfigParser()
    config.read_string("[dummysection]\n" + data)
    return dict(config['dummysection'])

print(read_properties(data))

输出:

{'first.key': '\\\nRight,\\\nSide,\\\nValue', 'second.key': 'Second value', 'third.key': 'Third value'}

如果您愿意,可以进一步处理它以删除\\\n

print({k: v.replace("\\\n", "") for k, v in read_properties(data).items()})

输出:

{'first.key': 'Right,Side,Value', 'second.key': 'Second value', 'third.key': 'Third value'}

【讨论】:

  • 这会给我 - configparser.ParsingError: Source contains parsing errors: ''
  • 能否提供一个不起作用的属性文件?
  • 我已经在第一篇中添加了。
【解决方案2】:

如果你不想使用配置解析器,我写了一个自定义解析器

import re

with open('delete.txt', "r") as file:
    data = file.read()
    # parsed_data = data.split('=')
    parsed_data = re.split('(?<=[^\\\\])\n', data)
    data_dict = {}
    for element in parsed_data:
        split = element.split('=')
        data_dict[split[0]] = split[1].split('\\\n')
    for key in data_dict:
        print(f"{key} : {data_dict[key]}")

输出:

first.key : ['', '        Right,', '        Side,', '        Value']
second.key : ['Second value']
third.key : ['Third value']

这个解析器绝对可以改进。但我想说困难的部分已经解决了

输入文件:

first.key=\
        Right,\
        Side,\
        Value
second.key=Second value
third.key=Third value

【讨论】:

  • 这会给我 - IndexError: list index out of range
  • 我添加了输入文件
  • 这种方法会将每个值添加为项目列表,并使 wnole 认为非常复杂,因为我必须提取和合并这些值。在多行值的情况下,它会将每一行添加为列表中的一个项目,并将删除“\\”这是一个问题。我看到它的方式,如果上一个项目以('//')结尾,我必须找到一种方法将列表中的下一个项目附加到上一个项目
【解决方案3】:

这会有帮助吗?

输入文件“multiline.txt”

first.key=\
        Right,\
        Side,\
        Value
second.key=Second value
third.key=Third value

代码

  • 创建了一个名为keyvals 的空字典。
  • 如果一行包含=,则通过拆分获取键值对。
  • 如果一行不包含=,则将该行附加到前一个值。
keyvals = {}
lines= open('multiline.txt', mode='r').read().splitlines()
for line in lines:
    if '=' in line:
        split = line.split('=')
        keyvals[split[0]] = split[1].replace('\\','').strip()
    else:
        keyvals[split[0]] += line.replace('\\','').strip()
print(keyvals)

注意事项:
splitlines() 处理换行符\n
strip() 删除文本前后的额外空格或制表符。

输出:

{'first.key': 'Right,Side,Value', 'second.key': 'Second value', 'third.key': 'Third value'}

【讨论】:

  • 这会给我 NameError: name 'split' is not defined
  • @myname 没有。
  • @myname Hm... 它可能引发该错误的唯一方法是如果文件的第一行是其他内容,其中没有 =,这与您显示的不同.
  • 代码与显示的相同,除了“r”,因为在上下文管理器中默认是阅读模式,所以不需要“r”,我已经更改了文件名。错误是因为 else 子句缺少“=”。即使你把“=”放在那里,我仍然会有 KeyError。
  • @myname,它在您最初提供的输入上没有任何错误,并提供您最初想要的输出。您现在更改了输入文件和所需的输出。
猜你喜欢
  • 1970-01-01
  • 2013-02-08
  • 2020-08-18
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
相关资源
最近更新 更多