web-dev-qa-db-fra.com

comment sélectionner les correspondances regex dans jinja2?

exemple de jouet

Essentiellement, je veux faire quelque chose comme:

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

Ce qui donnerait:

['Apple', 'rare']

de quoi je parle?

Les filtres match et select . Mon problème vient du fait que le filtre de sélection ne prend en charge que les "tests" unaires.

Je suis sur Ansible 1.9.x.

mon cas d'utilisation réel

... est plus proche de:

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

Donc, je veux obtenir tous les enregistrements PTR associés à une adresse IP, puis filtrer tous ceux qui ne correspondent pas à une expression régulière donnée. Je voudrais également m'assurer qu'il n'y a qu'un seul élément dans la liste résultante et afficher cet élément, mais c'est une préoccupation différente.

7
Parthian Shot

Ce modèle de conception a fonctionné pour moi:

----
- 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

Ça fera l'affraire?

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

Mise à jour: comment cela fonctionne ...

  • map applique filtres - les filtres ne sont pas des choses oui/non, ils s'appliquent à chaque élément de la liste d'entrée et de la liste de retour des éléments modifiés articles. J'utilise regex_search filtre, qui recherche le motif dans chaque élément et renvoie une correspondance s'il est trouvé ou Aucun s'il n'y a pas de correspondance. Donc, sur cette étape, je reçois cette liste: [null, "Apple", "rare", null, null].

  • Ensuite, nous utilisons select , qui applique tests - les tests sont des choses oui/non, donc ils réduisent la liste en fonction du test sélectionné . J'utilise string test, ce qui est vrai lorsque l'élément d'une liste est une chaîne. On obtient donc: ["Apple", "rare"].

  • map et select nous donnent quelques types internes python, donc nous convertissons en liste en appliquant le filtre list après tout.

9
Konstantin Suvorov

J'ai trouvé l'astuce suivante si vous souhaitez filtrer une liste dans Ansible (obtenir la liste avec des valeurs nulles et faire la différence avec une liste nulle):

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

Voici la sortie: ok: [localhost] => {"msg": ["Apple", "rare"]}

1
MVCaraiman