Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match literals with 'regex_replace' Ansible filter

Tags:

regex

ansible

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?

like image 650
luqo33 Avatar asked Sep 17 '16 09:09

luqo33


People also ask

Is it possible to match a string in Ansible?

It seems that "match" requires a pattern that matches the whole string, hence the *. before and after that string to be matched. Two separate "set_fact" stanzas are needed so that "keytype" is set before it is used. The code works in Ansible 2.4.3.0 running on Debian 9 (Raspbian "Stretch").

How to replace data in a string or variable using regex?

regex_replace or the replace filter can be used to replace data in a string or variable. The replace module is used to replace data in a file. In this example, Hello is replaced with Goodbye. - name: "replace 'Hello' with 'Goodbye'" debug: msg: " { { 'Hello World' | regex_replace ('Hello', 'Goodbye') }}"

When to use Ansible filters?

In Ansible, when we need data manipulation, processing, formatting and conversion. We have a set of filters, jinja2 template filters and custom filters created by users.

How do I make a variable optional in Ansible?

By default Ansible requires values for all variables in a templated expression. However, you can make specific variables optional. For example, you might want to use a system default for some items and control the value for others. To make a variable optional, set the default value to the special variable omit:


2 Answers

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.

like image 153
luqo33 Avatar answered Nov 14 '22 13:11

luqo33


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.

like image 32
Bohemian Avatar answered Nov 14 '22 14:11

Bohemian