如何有条件地用 regex_replace 替换列表中的文本?

How to conditionally replace text in a list with regex_replace?

我的剧本中有一个派生自列表的变量。在某些情况下,此变量包含一个“-”来分隔两个值。例如,

Numbers:
  - 2211
  - 2211-2212

在这种情况下,我想根据条件将“-”替换为“_”:如果数字长度为 4 个字符,请执行此操作。否则,将“-”替换为“_”并执行此操作。

我已经尝试 fiddle 在我的剧本中使用 jinja2 ans regex,但到目前为止还没有成功。这是我尝试过的,

number: {% if length(item) == 4 %} {{ item | regex_replace("^(.*)$", "Number_") | string }} {% else %} {{ item | regex_replace("^(.*)$", "Number_") |replace("-", "_") | string }}

我想要的结果,

Number is four characters long:
    number: Number_2211
Number is more then 4 characters long:
    number: Number_2211_2212 

我收到的一些错误消息是,

ERROR! Syntax Error while loading YAML.
  did not find expected key

ERROR! Syntax Error while loading YAML.
  found character that cannot start any token

有没有办法在 Ansible 剧本中实现这一点? 提前致谢!

您并不清楚您是如何尝试使用这些数据的。 Ansible 并不擅长 修改 复杂的数据结构,但它有很多方法可以在您访问数据时 转换数据 。例如,这个剧本:

---
- hosts: localhost
  gather_facts: false
  vars:
    numbers:
      - "2211"
      - "2211-2212"
  tasks:
    - debug:
        msg: "number: {{ item.replace('-', '_') }}"
      loop: "{{ numbers }}"

将输出:

TASK [debug] **********************************************************************************
ok: [localhost] => (item=2211) => {
    "msg": "number: 2211"
}
ok: [localhost] => (item=2211-2212) => {
    "msg": "number: 2211_2212"
}

如果您确实需要以长度为条件进行转换(并且不清楚您是否这样做),您可以这样做:

- debug:
    msg: "{{ item.replace('-', '_') if item|length > 4 else item }}"
  loop: "{{ numbers }}"

更新

我看到你选择了另一个答案。此处提供的解决方案似乎简单得多(没有 "incomprehensible sequence of filters, regex expressions, and equality checks"),并产生几乎相同的输出:

TASK [debug] **********************************************************************************
ok: [localhost] => (item=445533) => {
    "msg": "445533"
}
ok: [localhost] => (item=112234-538) => {
    "msg": "112234_538"
}
ok: [localhost] => (item=11) => {
    "msg": "11"
}
ok: [localhost] => (item=1111) => {
    "msg": "1111"
}
ok: [localhost] => (item=1111-1111) => {
    "msg": "1111_1111"
}
ok: [localhost] => (item=11-11) => {
    "msg": "11_11"
}

目前尚不清楚,给定 11-11,您希望输出 11_11 还是 11-11。如果你期望前者,这个答案更正确。

您可以使用一系列难以理解的过滤器、正则表达式和相等性检查来执行此操作。

#!/usr/bin/env ansible-playbook
- name: Lets munge some data
  hosts: localhost
  gather_facts: false
  become: false
  vars:
    array:
    - 445533
    - 112234-538
    - 11
    - 1111
    - 1111-1111
    - 11-11
  tasks:
  - name: Replace hypens when starting with 4 numbers
    debug:
      msg: "{{ ((item | string)[0:4] | regex_search('[0-9]{4}') | string != 'None') 
             | ternary((item | regex_replace('-', '_')), item) }}"
    loop: "{{ array }}"

PLAY [Lets munge some data] *****************************************************************************************************************************************************************************************************

TASK [Replace hypens when starting with 4 numbers] ******************************************************************************************************************************************************************************
ok: [localhost] => (item=445533) => {
    "msg": "445533"
}
ok: [localhost] => (item=112234-538) => {
    "msg": "112234_538"
}
ok: [localhost] => (item=11) => {
    "msg": "11"
}
ok: [localhost] => (item=1111) => {
    "msg": "1111"
}
ok: [localhost] => (item=1111-1111) => {
    "msg": "1111_1111"
}
ok: [localhost] => (item=11-11) => {
    "msg": "11-11"
}

PLAY RECAP **********************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0