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
相关产品推荐
相关产品推荐

