Ansible 或 Python,如何使用列表中的regex_findall返回以特定模式开头的单词



我主要在 ansible 中使用它,但我认为它在 python 中类似。所以我有一个字符串列表,我需要从中提取以某种模式开头的单词。例如,如果我有以下内容:

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

编辑:使用新要求进行了更新

虽然Frenchy的答案没有错,但它本质上会更慢,并且比Jinja2希望通过|select过滤器完成的方式更冗长,该过滤器专为处理列表项而设计:

- set_fact:
start_with_water: >-
{{ list1 | select('match', '^water')
| map('regex_findall', '([^ ]+) .*')
| map('first')
| list }}

生产

{
"ansible_facts": {
"start_with_water": [
"water_3gallons_6/20/22",
"water_1gal_today"
]
},
"changed": false
}

如果你好奇为什么你的regex_findall方法没有达到你的预期,那是因为该过滤器需要一个字符串输入,所以 jinja2 很有帮助(?) 通过调用str(list1)来强迫list[str]进入str,并将其输入到与任何"行首"不匹配的过滤器中,就像你期望的那样

regex_findall用于字符串:

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

结果:

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

为了避免when情况,您可以直接在列表中使用select

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

最新更新