Why doesn't Ansible like my regexp?

`

As far as I can tell I have all of my quotes… it just doesn’t seem to like my escaping… Adding verbosity didn’t give me any useful information.

`

`

  • name: Sanitize vm.cfg step 2 of
    lineinfile:
    path: “{{ file }}”
    regexp: “{{ item.regexp }}”
    line: “{{ item.line }}”
    backrefs: “{{ item.backrefs }}”
    with_items:
  • { regexp: “^(vif.*‘mac=)((\w{2}:){3})((\w{2}:?){3})(.+)’$”, line: “\1\2AA:{{ 99 | random(start=10, step=1) }}:{{ 99 | random(start=10, step=1) }}\6”: backrefs: yes }
  • { regexp: “(^uuid)(?:[=\s’]+)'(.)'.$”, line: “{{ newid.stdout }}”, backrefs: no }
  • { regexp: “(^name)(?:[=\s’]+)'(.)'.$”, line: “{{ newid.stdout }}”, backrefs: no }

`

Result:

`
ERROR! Syntax Error while loading YAML.
found unknown escape character

The error appears to have been in ‘/etc/ansible/playbooks/one-offs/test.yml’: line 46, column 37, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

with_items:

  • { regexp: “^(vif.*‘mac=)((\w{2}:){3})((\w{2}:?){3})(.+)’$”, line: “\1\2AA:{{ 99 | random(start=10, step=1) }}:{{ 99 | random(start=10, step=1) }}\6”: backrefs: yes }
    ^ here
    We could be wrong, but this one looks like it might be an issue with
    missing quotes. Always quote template expression brackets when they
    start a value. For instance:

with_items:

  • {{ foo }}

Should be written as:

with_items:

  • “{{ foo }}”

`

In my experience this is because of double quotes around regexp and line that contains backslash, it is treated as a string and do expand escapes.
You can avoid that by using single quotes instead, but then you need to escape the single quotes in you regexp.

What I do is avoid quotes all together, to do that you need to write your with_items in another style

  with_items:
    - regexp: ^(vif.*'mac=)((\w{2}:){3})((\w{2}:?){3})(.+)'$
      line: \1\2AA:{{ 99 | random(start=10, step=1) }}:{{ 99 | random(start=10, step=1) }}\6
      backrefs: yes
    - regexp: (^uuid)(?:[=\s']+)'(.*)'.*$
      line: "{{ newid.stdout }}"
      backrefs: no
    - regexp: (^name)(?:[=\s']+)'(.*)'.*$
      line: "{{ newid.stdout }}"
      backrefs: no

This should work and the double quotes in the line must be there since { after colon in yaml is treated as a dict.

Thanks Kai! That was the issue. No complaints from Ansible now.