diff --git a/docs/docsite/rst/reference_appendices/faq.rst b/docs/docsite/rst/reference_appendices/faq.rst index a0c25871178..a969fd4d0cc 100644 --- a/docs/docsite/rst/reference_appendices/faq.rst +++ b/docs/docsite/rst/reference_appendices/faq.rst @@ -811,6 +811,31 @@ and backups, which most file based modules also support: path: "{{ updated['backup_file'] }}" state: absent +.. _jinja2_faqs: + +Why does the ``regex_search`` filter return `None` instead of an empty string? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Until the jinja2 2.10 release, Jinja was only able to return strings, but Ansible needed Python objects in some cases. Ansible uses ``safe_eval`` and only sends strings that look like certain types of Python objects through this function. With ``regex_search`` that does not find a match, the result (``None``) is converted to the string "None" which is not useful in non-native jinja2. + +The following example of a single templating action shows this behavior: + +.. code-block:: Jinja + + {{ 'ansible' | regex_search('foobar') }} + +This example does not result in a Python ``None``, so Ansible historically converted it to "" (empty string). + +The native jinja2 functionality actually allows us to return full Python objects, that are always represented as Python objects everywhere, and as such the result of a single templating action with ``regex_search`` can result in the Python ``None``. + +.. note:: + + Native jinja2 functionality is not needed when ``regex_search`` is used as an intermediate result that is then compared to the jinja2 ``none`` test. + + .. code-block:: Jinja + + {{ 'ansible' | regex_search('foobar') is none }} + .. _docs_contributions: diff --git a/docs/docsite/rst/user_guide/playbooks_filters.rst b/docs/docsite/rst/user_guide/playbooks_filters.rst index aaec7cb157d..7e2f0de6efa 100644 --- a/docs/docsite/rst/user_guide/playbooks_filters.rst +++ b/docs/docsite/rst/user_guide/playbooks_filters.rst @@ -1826,16 +1826,20 @@ The ``regex_search`` filter returns an empty string if it cannot find a match: {{ 'ansible' | regex_search('foobar') }} # => '' -Note that due to historic behavior and custom re-implementation of some of the Jinja internals in Ansible there is an exception to the behavior. When used in a Jinja expression (for example in conjunction with operators, other filters, and so on) the return value differs, in those situations the return value is ``none``. See the two examples below: -.. code-block:: yaml+jinja +.. note:: + + + The ``regex_search`` filter returns ``None`` when used in a Jinja expression (for example in conjunction with operators, other filters, and so on). See the two examples below. + + .. code-block:: Jinja {{ 'ansible' | regex_search('foobar') == '' }} # => False - {{ 'ansible' | regex_search('foobar') == none }} + {{ 'ansible' | regex_search('foobar') is none }} # => True -When ``jinja2_native`` setting is enabled, the ``regex_search`` filter always returns ``none`` if it cannot find a match. + This is due to historic behavior and the custom re-implementation of some of the Jinja internals in Ansible. Enable the ``jinja2_native`` setting if you want the ``regex_search`` filter to always return ``None`` if it cannot find a match. See :ref:`jinja2_faqs` for details. To extract all occurrences of regex matches in a string, use the ``regex_findall`` filter: @@ -2038,7 +2042,7 @@ To split a string into a list: .. code-block:: yaml+jinja {{ csv_string | split(",") }} - + .. versionadded:: 2.11 To work with Base64 encoded strings: