10
votes

I cannot find a way to much a literal (a dot) in Ansible's regex_replace filter. Here is the task:

- name: Display database name
  debug:
    msg: "{{ vhost | regex_replace('(.+\.)(.+)$', \\1) }}"
  tags: [debug]

My intention is to match and replace the whole URL like test.staging.domain.com with its first part (test in the example).

Ansible would report the following error:

debug:
  msg: "{{ vhost | regex_replace('(.+\.)(.+)$', \\1) }}"
                                     ^ 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.

How can I match literals in Ansible regexp_replace filter?

3

3 Answers

12
votes

it's actually possible to escape literals with double backlashes:

- name: Create database name and username
  set_fact:
    db_name: "{{ vhost | regex_replace('([^\\.]*)\\.(.+)$', '\\1') }}_stg"

The regexp above works correctly. The first capturing group extracts the first part of the URL until the first dot, the whole regex captures the whole URL. Passing test.staging.domain.com through it would produce just test.

4
votes

I was trying to do the same thing, ended up doing it like this:

- name: Set hostname (minus the domain)
  debug: msg={{ inventory_hostname | regex_replace('^([^.]*).*', '\\1') }}

*edit, found a nicer way:

- name: Set hostname (minus the domain)
  debug: msg={{ inventory_hostname.split('.')[0] }}
3
votes

There could be something whacky about escaping characters, but there's an escape-less way to code a literal dot:

[.]

So your regex could be written

(.+[.])(.+)$

Most characters lose their special meaning when in a character class, and the dot is one of them.