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

Ansible 2.9中regex_search/regex_findall多字符串匹配结果异常

Ansible 2.9 筛选KVM列表条目问题排查与解决

问题场景

使用Ansible 2.9版本(无法升级基础设施),需从以下kvm_list列表中筛选出以kgit或kes开头的条目:

kvm_list:
  - abcdefabcfgh.domain.example
  - deffghabc.domain.example
  - abcblabla.domain.example
  - kabcxyz.domain.example
  - kesanu.domain.example
  - kesbapo.domain.example
  - kextoet.domain.example
  - kptfkom.domain.example
  - kgitblabla.domain.example
  - kgitblubblub.domain.example

执行以下任务后,结果意外包含了kextoet.domain.example和kptfkom.domain.example这两个不符合条件的条目:

- name: "get them devtools"
  hosts: localhost
  ignore_errors: True
  tasks: 
    - set_fact:
         devtools: "{{ kvm_list | string | regex_search('kgit.*|kes.*', multiline=True)}}"
    
    - debug: var=devtools

错误输出:

TASK [debug] **************************************************************************************************************************
ok: [localhost] => {
"msg":"kesanu.domain.example','kesbapo.domain.example','kextoet.domain.example','kptfkom.domain.example','kgitblabla.domain.example','kgitblubblub.domain.example]"
}

错误原因

将列表转为字符串后,格式类似['item1','item2','item3']。原正则kgit.*|kes.*中的.*会匹配任意字符直到换行,导致kes开头的条目后,字符串里的','kextoet...会被.*一并匹配,因为没有限制匹配的是单个完整条目,从而错误包含了中间的其他k开头条目。

解决方法

方法1:使用select+match过滤器(推荐)

Ansible 2.9原生支持select过滤器结合match测试,直接对列表元素逐个筛选,无需转成字符串:

- name: "get them devtools"
  hosts: localhost
  ignore_errors: True
  vars:
    kvm_list:
      - abcdefabcfgh.domain.example
      - deffghabc.domain.example
      - abcblabla.domain.example
      - kabcxyz.domain.example
      - kesanu.domain.example
      - kesbapo.domain.example
      - kextoet.domain.example
      - kptfkom.domain.example
      - kgitblabla.domain.example
      - kgitblubblub.domain.example
  tasks: 
    - set_fact:
         devtools: "{{ kvm_list | select('match', '^(kgit|kes)') | list }}"
    
    - debug: var=devtools
  • match测试默认验证字符串开头是否匹配正则,^(kgit|kes)明确指定匹配以kgit或kes开头的内容
  • select会过滤出所有符合条件的元素,最后用list转为列表格式

方法2:修正正则表达式(不推荐,仅作兼容参考)

如果坚持使用字符串转义的方式,需修改正则以匹配单个完整条目:

- name: "get them devtools"
  hosts: localhost
  ignore_errors: True
  vars:
    kvm_list:
      - abcdefabcfgh.domain.example
      - deffghabc.domain.example
      - abcblabla.domain.example
      - kabcxyz.domain.example
      - kesanu.domain.example
      - kesbapo.domain.example
      - kextoet.domain.example
      - kptfkom.domain.example
      - kgitblabla.domain.example
      - kgitblubblub.domain.example
  tasks: 
    - set_fact:
         devtools: "{{ kvm_list | string | regex_findall(\"'((kgit|kes)[^']+)'\") | list }}"
    
    - debug: var=devtools
  • '((kgit|kes)[^']+)'匹配被单引号包裹、以kgit/kes开头且后续不含单引号的内容,确保只匹配单个条目
  • regex_findall提取所有符合条件的内容,得到正确列表

验证结果

两种方法最终都会输出正确的筛选结果:

ok: [localhost] => {
    "devtools": [
        "kesanu.domain.example",
        "kesbapo.domain.example",
        "kgitblabla.domain.example",
        "kgitblubblub.domain.example"
    ]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 04:06:25