首页 > 解决方案 > 使用 Python 解析 YAML 文件,以提取唯一/非唯一关键字对之间的文本块

问题描述

我有一个程序需要能够从 YAML 文件中提取文本块,对其进行哈希处理,将其与上次“运行”进行比较,然后根据结果做出决定。有问题的代码:

 21     def parse_file(self):                                                        
 22     ¦   webservers_template = os.path.abspath('templates/webservers.yaml')       
 23     ¦   with open(webservers_template, 'rb') as stream:                          
 24     ¦   ¦   try:                                                                 
 25     ¦   ¦   ¦   print(stream.read())                                             
 26     ¦   ¦   ¦   metadata_blob = re.findall(r'\n    Metadata:(.*?)\n    Properties:', str(stream)
    )                                                                                               
 27     ¦   ¦   ¦   print(metadata_blob)                                             
 28     ¦   ¦   ¦   return bytes(metadata_blob)                                      
 29     ¦   ¦   except yaml.YAMLError as exc:                                        
 30     ¦   ¦   ¦   print(exc)        

该文件templates/webservers.yaml是一个基于 YAML 的 cloudformation 模板。看起来像这样

我要执行的操作是我有一个唯一关键字Metadata和一个非唯一关键字Properties,我想返回这两个关键字之间的所有文本,它的格式除了可靠性之外没有任何要求,它必须始终以相同的方式返回,因为它将是散列函数的输入,自然我将散列函数的输出用于差异操作,因此误报将无济于事。

我目前遇到的问题print(metadata_blob)是没有返回任何东西,它只是返回给我一个空列表。

为了让您对我正在执行的操作有一个模糊的了解,我试图绕过一些 AWS 功能,以便在我更改 LaunchConfiguration 元数据时引发 UpdatePolicy 操作。不过,这对于这个问题可能并不重要。

我对这个有点迷茫,如果我目前解决这个问题的方法没有意义,请随时为我指出一个更合适的方向。

我在写这篇文章时读过一些问题并从中“借用”了一些想法。

如何在 Python 中解析 YAML 文件

如何在大文本文件中提取两个唯一单词之间的信息

标签: pythonregexparsingyaml

解决方案


考虑到您链接的测试数据print(metadata_blob),返回一个空列表是完全正确的,因为Metadata:YAML 中没有。

更重要的是,您这样做print(stream.read())会读取整个文件并将流的位置放在文件的末尾。之后,每次尝试读取stream都不会返回任何内容。我的 Python 不够强大,无法知道你这样做时究竟会发生什么,str(stream)但这绝对不是从文件中读取任何内容的常用方法。

尝试这个:

contents = stream.read()
print(contents)
metadata_blob = re.findall(r'\n    Metadata:(.*?)\n    Properties:', contents)

此外,不要使用 try/catch 或做一些有用的事情。您永远不会得到 a yaml.YAMLError,因为您不使用yaml模块来读取文件。


推荐阅读