【问题标题】:How to match a regex on an array name itself in jmespath (json element string regex wildcard)如何在 jmespath 中匹配数组名称本身的正则表达式(json 元素字符串正则表达式通配符)
【发布时间】:2021-03-17 16:44:34
【问题描述】:

如何使用jmespath 中的正则表达式在 json 中搜索数组?

考虑以下 JSON 文档(如果结构不佳,请放在一边):

{
  "people_in_town": [
    {"letter": "a"},
    {"letter": "b"},
  ],
  "people_with_shoes": [
    {"letter": "c"},
    {"letter": "d"},
  ],
  "people_with_town": [
    {"letter": "e"},
    {"letter": "f"},
  ],
}

现在,jmespath 可以轻松地对列表的所有元素进行通配符,这样people_in_town[*].letter 将返回[a, b]

但我想使用的通配符是数组名称的正则表达式,如下所示:

people_*_town.letter

这样它将返回people_in_townpeople_with_town 的内容,以及任何包含people_ 后跟<some string> 后跟_town 的数组。当然,上面的例子是行不通的。

如何使用 jmespath 将 json 文档中的数组与正则表达式匹配?

【问题讨论】:

  • 你的用例是真的做foo_*_bar(注意这是一个通配符而不是一个正则表达式,实际上)还是做foo_abc_bar OR foo_def_bar OR foo_ghi_bar?当第一个很可能不可能时,第二个肯定是。
  • 这个问题是为第一个问题创建的,jmespath 文档中明显没有。为简单起见,我使用了通配符,但首选正则表达式。
  • JMESPath 中没有正则表达式这样的东西。虽然有一张票可以尝试安装:github.com/jmespath/jmespath.py/issues/213

标签: arrays json regex wildcard jmespath


【解决方案1】:

只是涵盖了您从linked question 添加的用例,而不是真正通用的关键问题中的通配符,这很可能是不可能的.

但如果你确实有类似的问题要查询

key in ['people_in_town', 'people_with_town']

因此,使用有限数量的已知密钥,那么您绝对可以执行类似的操作

[@.people_in_town, @.people_with_town][].letter

那会给出:

[
  "a",
  "b",
  "e",
  "f"
]

使用纯 JMESPath 方法您将面临的主要问题是,您可以对键执行的唯一操作是基于 keys 函数,遗憾的是不可能同时拥有这两个键数组然后来返回该部分以选择这些键。

如果你真的想只使用 JMESPath,那么,你必须以两遍结束:

  1. 使用keysstarts_with/ends_with 函数创建键列表
  2. 然后执行第二遍以返回上述查询

从 Ansible 的角度来看,这最终会得到这个非常丑陋的剧本:

- hosts: all
  gather_facts: no

  tasks:
    - debug: 
        msg: >-
          {{
              data | json_query(
                "[@." ~ data | json_query(
                  "join(
                    ',@.', 
                    keys(@)[?
                      starts_with(@, 'people_') 
                      && ends_with(@, '_town')
                    ]
                  )"
                ) ~ "][].letter"
              )
          }}
      vars:
        data:
          people_in_town:
            - letter: a
            - letter: b
          people_with_shoes:
            - letter: c
            - letter: d
          people_with_town:
            - letter: e
            - letter: f

结果

PLAY [all] *******************************************************************************************

TASK [debug] *****************************************************************************************
ok: [localhost] => 
  msg:
  - a
  - b
  - e
  - f

PLAY RECAP *******************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

所以,如果我真的是你,我会坚持linked question 的答案中提出的选项,并在这个特定用例中远离 JMESPath。

【讨论】:

    猜你喜欢
    • 2015-11-16
    • 2012-06-05
    • 2013-12-25
    • 1970-01-01
    相关资源
    最近更新 更多