Escaping special characters in regex_replace with '\' fails with: unknown escape character

1,903 views
Skip to first unread message

jean-christophe manciot

unread,
Feb 3, 2021, 1:49:44 PM2/3/21
to Ansible Project
ansible: 2.10.5 (with pip3 install)
python version = 3.9.1+ (default, Jan 20 2021, 14:49:22) [GCC 10.2.1 20210110]

Escaping special characters in the searched string such as the following should be simply done with '\':
- ' --> \'
- ( --> \(
- , --> \,
- ) --> \)

However, it seems to be impossible to perform this task with a single '\' or even a double '\\'; for instance, running the following playbook fails:
```
---
- name: Escaping special characters in regex_replace fails
  hosts:
        - localhost
  strategy: debug
  vars:
        searched_string: "('string_a', 'string_b'),('string_c', 'string_d')"
  tasks:
        - name: Escaping with '\' - Result expected is "string_a@string_b,string_c@string_d"
          set_fact:
                replaced_string: "{{ searched_string |
                                     regex_replace('\(\'([^\']+)\'\, \'([^\']+)\'\)', '\\1@\\2') }}"
...
```
leads to:
```
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0)

Syntax Error while loading YAML.
  found unknown escape character

The error appears to be in 'escape_special_characters_in_regex_replace.yml': line 16, column 53, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

                replaced_string: "{{ searched_string |
                                     regex_replace('\(\'([^\']+)\'\, \'([^\']+)\'\)', '\\1@\\2') }}"
                                                    ^ here
```

I thought about using the jinja2 'replace' filter to remove all special characters first, but that would just be throwing the can down the road, right? ;-)

What am I missing?


jean-christophe manciot

unread,
Feb 3, 2021, 1:56:47 PM2/3/21
to Ansible Project
I meant kicking ...., but you got the idea.

Felix Fontein

unread,
Feb 3, 2021, 1:58:16 PM2/3/21
to ansible...@googlegroups.com
Hi,

the problem is that you're inside a YAML " " string, which already
interprets escaping.

Try using `>-` or something like that (https://yaml-multiline.info/)
instead of double quotes for the string that's templated, like

replaced_string: >-
{{ searched_string | regex_replace(
'\(\'([^\']+)\'\, \'([^\']+)\'\)', '\\1@\\2') }}

Then it should work.

(Alternatively, if you use " ", you need to double escape - which is
extremely ugly to read.)

Cheers,
Felix




On Wed, 3 Feb 2021 10:49:44 -0800 (PST)
jean-christophe manciot <actionm...@gmail.com> wrote:

> ansible: *2.10.5* (with pip3 install)

Vladimir Botka

unread,
Feb 3, 2021, 7:45:07 PM2/3/21
to jean-christophe manciot, ansible...@googlegroups.com
On Wed, 3 Feb 2021 10:49:44 -0800 (PST)
jean-christophe manciot <actionm...@gmail.com> wrote:

> vars:
> searched_string: "('string_a', 'string_b'),('string_c', 'string_d')"
> ...
> Result expected is "string_a@string_b,string_c@string_d"
> ...
> set_fact:
> replaced_string: "{{ searched_string |
> regex_replace('\(\'([^\']+)\'\,
> \'([^\']+)\'\)', '\\1@\\2') }}"

FWIW, create lists and join the items

- set_fact:
replaced_string: "{{ searched_lists|
map('join', '@')|list|
join(',') }}"
vars:
pleft: '\('
pright: '\)'
bleft: '['
bright: ']'
searched_lists: "{{ searched_string|
regex_replace(pleft, bleft)|
regex_replace(pright, bright) }}"

--
Vladimir Botka

Vladimir Botka

unread,
Feb 4, 2021, 2:28:49 AM2/4/21
to jean-christophe manciot, ansible...@googlegroups.com
This simplified version gives the same result

- set_fact:
replaced_string: "{{ searched_lists|
map('join', '@')|list|
join(',') }}"
vars:
searched_lists: "{{ '[' ~ searched_string ~ ']' }}"


--
Vladimir Botka

jean-christophe manciot

unread,
Feb 4, 2021, 10:03:09 AM2/4/21
to Ansible Project
@Felix Fontein
I tried to replace the double-quotes with:
-  >-: "An unhandled exception occurred while templating"
- '>: "An unhandled exception occurred while templating"

@Vladimir Botka
Fantastic :-)
I chose the last version.

Reply all
Reply to author
Forward
0 new messages