Trying to replace single quote with regex_replace

Hello, all.

I’m working with VMware modules in removing snapshots across all vCenter folders. In order for this to work, I first have to get the folders in which the virtual machines live. Here’s the playbook:

Have you tried:

regex_replace(‘(\[)|(\])|(\')’, ‘’)

Walter

Hi, Walter.

Yes, and it fails:

fatal: [api-dev-01 → localhost]: FAILED! => {
“msg”: “template error while templating string: expected token ‘end of print statement’, got ‘string’. String: {{ vm_facts.folders | regex_replace(‘(\\[)|(\\])|(\\’)', ‘’) }}. expected token ‘end of print statement’, got ‘string’”
}

This works.

regex_replace("([\[\]‘])",’')

Escaping the double quotes that define the search regex gets around needing to escape the single quote. Also note that I collapsed your search into a single character set.

Walter, that worked, and thanks so much! I both appreciate the regex solution, and it simplification. I also probably be able to reuse this, with some modifications, depending on what I’m trying to accomplish. Double win. Thanks again!

Walter, to further my knowledge, would you mind explaining further what this regex "([\[\]‘])",’ does? Is the regex specifi to regex_replace?

In plain terms it is really this:

[']

The outside square brackets define a character set. The characters in between mean “any of these”.

Since square brackets define a character set we have to escape the inside square brackets to be see as characters in the set.

[']

Since this is ansible we have to escape the backslashes.

[\[\]']

You could place any characters in that set. The regex matches any of them any number of times.

For example I could use [walter] and it would look for any of those characters.

You also can use ranges like [a-dv-z]. This all follows Python regex rules.

Walter

"['/First Datacenter/vm/Prod-SRM']"
The problem is [' and ']. They can't be part pf the folder name.

FWIW, convert the string to a list

s: "['/First Datacenter/vm/Prod-SRM']"
l: "{{ s|from_yaml }}"

gives

l.0: /First Datacenter/vm/Prod-SRM

Even better! Brilliant!

Walter

Thanks, Vladimir. Forgive my stupidity but, for my edification, how is that actually written in the playbook?

> FWIW, convert the string to a list
>
> s: "['/First Datacenter/vm/Prod-SRM']"
> l: "{{ s|from_yaml }}"

how is that actually written in the playbook?

For example,

cat pb1.yml

- hosts: all
  vars:
    s: "['/First Datacenter/vm/Prod-SRM']"
    l: "{{ s|from_yaml }}"
  tasks:
    - debug:
        var: l|type_debug
    - debug:
        var: l.0

gives (abridged)

  l>type_debug: list
  l.0: /First Datacenter/vm/Prod-SRM

But, the code in your first email shows you get *vm_facts* as
registered output of *community.vmware.vmware_guest_find*. Take a
look at the Return Values of this module
https://docs.ansible.com/ansible/latest/collections/community/vmware/vmware_guest_find_module.html#return-values

The documentation says *folders* is "list/elements=string". In this
case, no conversion is needed to get the element of the list. For
example,

cat pb2.yml

- hosts: all
  vars:
    vm_facts:
      folders: ['/First Datacenter/vm/Prod-SRM']
  tasks:
    - debug:
        var: vm_facts.folders|type_debug
    - debug:
        var: vm_facts.folders.0

gives (abridged)

  vm_facts.folders|type_debug: list
  vm_facts.folders.0: /First Datacenter/vm/Prod-SRM

FWIW, try community.general.yaml callback. YAML is much easier to
read compared to JSON. See
https://docs.ansible.com/ansible/latest/collections/community/general/yaml_callback.html