如何在jinja2中选择正则表达式匹配?

Par*_*hot 6 template-engine jinja2 ansible

玩具的例子

基本上,我想做的事情如下:

['hello', 'apple', 'rare', 'trim', 'three'] | select(match('.*a[rp].*'))
Run Code Online (Sandbox Code Playgroud)

哪个会产生:

['apple', 'rare']
Run Code Online (Sandbox Code Playgroud)

我在说什么?

match过滤器和select过滤器.我的问题源于select过滤器仅支持一元"测试".

我在Ansible 1.9.x.

我的实际用例

......更接近:

lookup('dig', ip_address, qtype="PTR", wantList=True) | select(match("mx\\..*\\.example\\.com"))
Run Code Online (Sandbox Code Playgroud)

所以,我希望获得与IP相关的所有PTR记录,然后过滤掉所有不适合给定正则表达式的记录.我还想确保结果列表中只有一个元素,并输出该元素,但这是一个不同的问题.

Kon*_*rov 9

这会吗?

---
- hosts: localhost
  connection: local
  vars:
    my_list: ['hello', 'apple', 'rare', 'trim', 'three']
    my_pattern: '.*a[rp].*'
  tasks:
    - set_fact: matches="{{ my_list | map('regex_search',my_pattern) | select('string') | list }}"
      failed_when: matches | count > 1
    - debug: msg="I'm the only one - {{ matches[0] }}"
Run Code Online (Sandbox Code Playgroud)

更新:它是如何工作的......

  • map应用过滤器 - 过滤器不是是/否,它们应用于输入列表的每个项目并返回已修改项目的列表.我使用 regex_search过滤器,在每个项目中搜索模式,如果找到则返回匹配,如果没有匹配,则返回None.所以在这一步我得到这个清单:[null, "apple", "rare", null, null].

  • 然后我们使用select,它应用测试 - 测试是/不是,所以他们根据选择的测试减少列表.我使用stringtest,当列表项为字符串时为true.所以我们得到:["apple", "rare"].

  • mapselect给我们一些内部python类型,所以我们list毕竟通过应用过滤器转换为列表.


Par*_*hot 3

这种设计模式对我有用:

----
- hosts: localhost
  connection: local
  vars:
    my_list: ['hello', 'apple', 'rare', 'trim', "apropos", 'three']
    my_pattern: 'a[rp].*'
  tasks:
    - set_fact:
        matches: "{%- set tmp = [] -%}
                  {%- for elem in my_list | map('match', my_pattern) | list -%}
                    {%- if elem -%}
                      {{ tmp.append(my_list[loop.index - 1]) }}
                    {%- endif -%}
                  {%- endfor -%}
                  {{ tmp }}"
    - debug:
        var: matches
      failed_when: "(matches | length) > 1"
Run Code Online (Sandbox Code Playgroud)