Home > Mobile >  Ansible or Python, how to use regex_findall on a list to return words that start with a certain patt
Ansible or Python, how to use regex_findall on a list to return words that start with a certain patt

Time:06-21

I am mainly using this in ansible but I figured its similar in python. So I have a list of strings which I need to extract words from it that start with a certain pattern. For example if I have the following:

list1: ['water_3gallons_6/20/22   490832', 'applejuice_1liter_6/18/22    490833', 'soda_2liters_6/22/22     490834', 'water_1gal_today      490835']

# and lets say I only want to pull the words that start with water (ignoring the 490832 part)
# meaning it should return this list: ['water_3gallons_6/20/22','water_1gal_today']

# I was using the following 2 codes and it was returning an empty list

- name: "Create list of words that start with water from list1 variable"
  set_fact:
     start_with_water: "{{ list1 |regex_findall('^water') }}" # RETURNED EMPTY LIST

- name: "Create list of words that start with water from list1 variable"
  set_fact:
     start_with_water: "{{ list1 |regex_findall('\\Awater') }}" # RETURNED EMPTY LIST TOO

CodePudding user response:

While Frenchy's answer isn't wrong, it will be inherently slower and is a lot more verbose than the way Jinja2 wants that done which is via the |select filter, designed for working with list items:

- set_fact:
     start_with_water: "{{ list1 | select('match', '^water') | list }}"

In case you were curious why your approach with regex_findall did not do what you expected, it's because that filter wants a string input, so jinja2 helpfully(?) coerced the list[str] into str by calling str(list1) and fed that into the filter which didn't match any "start of line" like you expected

CodePudding user response:

regex_findall is used on string:

  tasks:
    - name: get data
      set_fact:
        start_with_water: "{{ start_with_water | d([])   [item] }}"
      loop: "{{ list1 }}"
      when: item | regex_findall('^water')
    - name: display
      debug:
        msg: "{{ start_with_water }}"

result:

ok: [localhost] => {
    "msg": [
        "water_3gallons_6/20/22   490832",
        "water_1gal_today      490835"
    ]
}

to avoid when condition, you could use select directly on list:

  tasks:
    - set_fact:
        start_with_water: "{{ list1|select('regex', '^water')|list }}"
  • Related