You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible/Python如何用regex_findall提取列表指定前缀开头的内容

问题根因

之前的写法返回空列表、拿不到预期结果,核心是两个用法错误:

  • regex_findall过滤器的输入参数必须是字符串,直接传入列表时不会自动遍历每个列表元素做匹配,只会对列表的整体序列化结果做正则匹配,自然找不到目标内容
  • 所用的正则^water/\Awater仅能匹配开头的water这5个字符,既不会提取water后面跟随的前缀内容,也不会裁剪掉条目末尾的空格+数字编号段,完全不符合提取需求
可用实现方案

以下两种写法都可以直接拿到你预期的结果列表['water_3gallons_6/20/22','water_1gal_today']:

方案1:筛选+裁剪组合写法(可读性最好)

通过select筛选符合前缀要求的条目,再通过正则替换裁掉末尾的无用编号段,逻辑清晰好维护:

- name: 提取所有以water开头的内容前缀
  set_fact:
    start_with_water: "{{ list1 | select('search', '^water') | map('regex_replace', '\\s+\\d+$', '') | list }}"

各段过滤器作用:

  • select('search', '^water'):遍历列表所有元素,保留以water开头的条目,过滤掉其余不相关内容
  • map('regex_replace', '\\s+\\d+$', ''):对筛选出的每个条目,将末尾连续空格+行尾数字的部分替换为空,正好裁掉后面的4908xx编号
  • list:将迭代器转换为标准Ansible列表格式

方案2:纯regex_findall写法

如果要坚持用regex_findall实现,必须先通过map遍历列表元素,同时写对匹配规则,自动在第一个空格处截断:

- name: 通过regex_findall提取目标内容
  set_fact:
    start_with_water: "{{ list1 | map('regex_findall', '^water\\S+') | flatten | list }}"

这里正则^water\\S+的匹配逻辑是:从行首开始匹配water,之后连续匹配所有非空白字符,遇到第一个空格就停止,正好自动排除后面的编号段;最后用flatten把每个元素匹配生成的子列表拍平为一维普通列表即可。

避坑说明
  • Ansible的字符串处理过滤器默认不会自动遍历列表,处理列表元素必须配合map/select这类迭代类过滤器使用
  • 写正则时要明确匹配范围,只写开头关键词只能拿到关键词本身,拿不到完整的目标片段
  • 如果要匹配行首/字符串开头,在search/match测试里直接用^即可,不需要额外转义

内容的提问来源于stack exchange,提问作者NewbChewbCS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:36:21