web-dev-qa-db-ja.com

jinja2で正規表現一致を選択する方法?

おもちゃの例

基本的に、私は次のようなことをしたいです:

['hello', 'Apple', 'rare', 'trim', 'three'] | select(match('.*a[rp].*'))

これは次のようになります:

['Apple', 'rare']

私は何について話しているのですか?

match フィルターおよび select フィルター。私の問題は、selectフィルターが単項「テスト」のみをサポートするという事実から生じます。

Ansible 1.9.xを使用しています。

私の実際の使用例

...に近い:

lookup('Dig', ip_address, qtype="PTR", wantList=True) | select(match("mx\\..*\\.example\\.com"))

したがって、IPに関連付けられているすべてのPTRレコードを取得し、特定の正規表現に適合しないすべてのレコードをフィルターで除外する必要があります。また、結果のリストに要素が1つだけあることを確認し、その要素を出力したいと思いますが、それは別の問題です。

7
Parthian Shot

この設計パターンは私にとってうまくいきました:

----
- 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"
2
Parthian Shot

これでいいですか?

---
- 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] }}"

更新:仕組み...

  • map が適用されますfilters–フィルターは「はい/いいえ」ではなく、入力リストのすべてのアイテムに適用され、変更されたリストを返しますアイテム。私はregex_searchフィルターを使用します。これは、すべてのアイテムの検索パターンで、一致が見つかった場合は一致を返し、一致がない場合はNoneを返します。したがって、このステップで私は次のリストを取得します:[null, "Apple", "rare", null, null]

  • 次に select を使用しますtestsが適用されます–テストはyes/noであり、選択されたテストに基づいてリストを減らします。 stringテストを使用します。これは、リストの項目が文字列の場合に当てはまります。つまり、["Apple", "rare"]を取得します。

  • mapselectはいくつかの内部python=型を提供するため、結局listフィルターを適用してリストに変換します。

9

Ansibleでリストをフィルター処理したい場合は、次のトリックを見つけました(null値でリストを取得し、nullリストで違いを作ります):

---
- hosts: localhost
  connection: local
  vars:
    regexp: '.*a[rp].*'
    empty: [null]
  tasks:
    - set_fact: matches="{{ ['hello', 'Apple', 'rare', 'trim', 'three'] | map('regex_search',regexp)  | list|difference(empty) }}"
    - debug: msg="{{ matches }}"

次に出力を示します。ok:[localhost] => {"msg":["Apple"、 "rare"]}

1
MVCaraiman