Ansible: regex to search for a specific string in list

Viewed 1752

I have a list of strings called somelist as shown below. How do I specify a regex to search for the string name: bob - note that this should not match with name: bobby. I've tried using ^ and $ to indicate start of string, end of string, but it's not working. Also the colon is causing the following error: syntax error - mapping values are not allowed in this context. I can't figure out how to escape the colon. Thank you!

---
 - hosts: localhost

   vars:
     somelist:
      - "name: greg"
      - "name: bobby"
      - "name: joe"

   tasks:
   - debug: msg='{{ somelist is search("^name: bob$") }}'   # <--- this should equate to false

   - debug: msg='{{ somelist is search("^name: bobby$") }}' # <--- this should equate to true
2 Answers

Use select and test the length. For example

    - debug:
        msg: "{{ somelist|
                 select('search', '^name: bob$')|
                 list|length > 0 }}"   # <--- this should equate to false

    - debug:
        msg: "{{ somelist|
                 select('search', '^name: bobby$')|
                 list|length > 0 }}"   # <--- this should equate to true

gives (abridged)

  msg: false

  msg: true

Collon ":" isn't Python regex special character. It's not necessary to escape it. Putting the regex into a variable simplifies the condition. For example, the tasks below

    - debug:
        msg: bob is in the list
      when: somelist|select('search', regex)|list|length > 0
      vars:
        regex: '^name: bob$'
    - debug:
        msg: bobby is in the list
      when: somelist|select('search', regex)|list|length > 0
      vars:
        regex: '^name: bobby$'

gives (abridged)

skipping: [localhost]

ok: [localhost] => 
  msg: bobby is in the list

It's possible to avoid regex. For example, map from_yaml, create a list of dictionaries, and selectattr. The tasks below give the same results

    - debug:
        msg: "{{ somelist|
                 map('from_yaml')|
                 selectattr('name', 'eq', 'bob')|
                 list|length > 0 }}"

    - debug:
        msg: "{{ somelist|
                 map('from_yaml')|
                 selectattr('name', 'eq', 'bobby')|
                 list|length > 0 }}"

to search element on list, use the select attribute. you can remove the "name: " on your list as it's still the same to every elt.

---
 - hosts: localhost

   vars:
     somelist:
      - "greg"
      - "bobby"
      - "joe"
   tasks:
     - debug:
        msg: "{{ somelist|select('equalto', 'bobby')|list|length }}" 

Or you can check if the list contain the element:

---
 - hosts: localhost

   vars:
     somelist:
      - "greg"
      - "bobby"
      - "joe"
   tasks:
     vars:
    somelist:
      - "greg"
      - "bobby"
      - "joe"
    name_to_search: 'bobby'
  tasks:
    - debug:
        msg: "The list has bobby elt"
      when: name_to_search in somelist
 
Related