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

Ansible regex_findall捕获组结果顺序反转实现方法问询

Ansible regex_findall捕获组结果顺序反转实现方法问询

嗨,我完全明白你现在的困惑——用Ansible的regex_findall捕获组后,想把设备名(比如vda)和文件路径的顺序反过来对吧?这其实不难,咱们一步步来解决:

首先先明确一个关键点:regex_findall返回的捕获组顺序是完全和你正则表达式里写的括号顺序一致的,绝对不是随机的。你当前的正则里先写了匹配文件路径的括号(.+?)(第一个捕获组),再写了匹配设备名的括号(\w+)(第二个捕获组),所以结果里每个子列表自然是[文件路径, 设备名]的顺序。

接下来,给你两种可靠的方法来反转这个顺序:

方法一:用map('reverse')直接反转子列表顺序

这是最稳妥且不需要修改正则的方式,只需要在regex_findall的结果后加上map('reverse')和list过滤器,就能把每个子列表的元素顺序反转过来。修改你的任务如下:

- name: Get list of block device with reversed order
  set_fact:
    listblockdev: "{{ cleanxml | regex_findall(_q) | map('reverse') | list }}"
  vars:
    _q: "<disk type='file' device='disk'>.*?source file='(.+?)'.*?<target dev='(\\w+)'"

执行后你会得到预期的结果:

ok: [testhost] => {
    "msg": [
        [
            "vda",
            "/var/lib/libvirt/images/win01.qcow2"
        ],
        [
            "vdb",
            "/var/lib/libvirt/images/win01-1.qcow2"
        ]
    ]
}

方法二:调整正则里的捕获组顺序(需注意匹配逻辑)

如果你愿意修改正则表达式,可以调换两个捕获组的位置,但要注意XML标签的顺序——你的XML里<source>标签在<target>标签前面,所以要调整正则的匹配顺序,确保先找到<target>再回溯匹配<source>(不过这种方式可能存在匹配不稳定的风险,不如第一种方法可靠)。示例如下:

- name: Get list of block device with adjusted regex
  set_fact:
    listblockdev: "{{ cleanxml | regex_findall(_q) }}"
  vars:
    _q: "<disk type='file' device='disk'>.*?<target dev='(\\w+)'.*?source file='(.+?)'"

需要提醒你的是:你设想的cleanxml | regex_findall(_q, '\\2', '\\1')这种写法是行不通的,因为Ansible的regex_findall过滤器并不支持直接指定捕获组的输出顺序,必须通过后续的列表处理来调整。

备注:内容来源于stack exchange,提问作者Billy K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 08:25:30