regex 在Python中解析Yaml:检测重复密钥

628mspwn  于 2023-05-01  发布在  Python
关注(0)|答案(3)|浏览(147)

python中的yaml库无法检测重复的键。这是一个has been reported years ago的bug,目前还没有修复。
我想找到一个体面的解决这个问题。创建一个返回所有密钥的regex有多合理?那么就很容易发现这个问题。
有没有正则表达式大师能建议一个正则表达式,它能提取所有的键来找到重复的键?
文件示例:

mykey1:
    subkey1: value1
    subkey2: value2
    subkey3:
      - value 3.1
      - value 3.2
mykey2:
    subkey1: this is not duplicated
    subkey5: value5
    subkey5: duplicated!
    subkey6:
       subkey6.1: value6.1
       subkey6.2: valye6.2
7cwmlq89

7cwmlq891#

yamllint命令行工具可以完成您想要的任务:

sudo pip install yamllint

具体地说,它有一个规则key-duplicates,可以检测重复和相互覆盖的密钥:

$ yamllint test.yaml
test.yaml
  1:1       warning  missing document start "---"  (document-start)
  10:5      error    duplication of key "subkey5" in mapping  (key-duplicates)

(It有许多其他的规则,您可以启用/禁用或调整。)

hmtdttj4

hmtdttj42#

覆盖内置加载器是一种更轻量级的方法:

import yaml
 # special loader with duplicate key checking
 class UniqueKeyLoader(yaml.SafeLoader):
     def construct_mapping(self, node, deep=False):
         mapping = []
         for key_node, value_node in node.value:
             key = self.construct_object(key_node, deep=deep)
             assert key not in mapping
             mapping.append(key)
         return super().construct_mapping(node, deep)

然后:

yaml_text = open(filename), 'r').read()
 data[f] = yaml.load(yaml_text, Loader=UniqueKeyLoader)
wlzqhblo

wlzqhblo3#

ErichBSchulz非常努力。谢谢你的固定代码。我在这里做了一些小改动。使用行和列更新文件名。

class UniqueKeyLoader(yaml.SafeLoader):
    def construct_mapping(self, node, deep=False):
        mapping = set()
        for key_node, value_node in node.value:
            each_key = self.construct_object(key_node, deep=deep)
        if each_key in mapping:
            raise ValueError(f"Duplicate Key: {each_key!r} is found in YAML File.\n"
                             f"Error File location: {key_node.end_mark}")
        mapping.add(each_key)
        return super().construct_mapping(node, deep)

with open(test_suite_full_path, 'r') as f:
    yaml_ret_dict = yaml.load(f, Loader=UniqueKeyLoader)

相关问题