Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

regex_escape: support POSIX basic regex #50327

Merged
merged 3 commits into from
Mar 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions changelogs/fragments/regex-escape-basic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
minor_changes:
- |
regex_escape - added re_type option to enable escaping POSIX BRE chars

This distinction is necessary because escaping non-special chars such as
'(' or '{' turns them into special chars, the opposite of what is intended
by using regex_escape on strings being passed as a Basic Regular
Expression.
9 changes: 8 additions & 1 deletion docs/docsite/rst/user_guide/playbooks_filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1071,11 +1071,18 @@ To replace text in a string with regex, use the "regex_replace" filter::

.. versionadded:: 2.0

To escape special characters within a regex, use the "regex_escape" filter::
To escape special characters within a standard python regex, use the "regex_escape" filter (using the default re_type='python' option)::

# convert '^f.*o(.*)$' to '\^f\.\*o\(\.\*\)\$'
{{ '^f.*o(.*)$' | regex_escape() }}

.. versionadded:: 2.8

To escape special characters within a POSIX basic regex, use the "regex_escape" filter with the re_type='posix_basic' option::

# convert '^f.*o(.*)$' to '\^f\.\*o(\.\*)\$'
{{ '^f.*o(.*)$' | regex_escape('posix_basic') }}


Kubernetes Filters
``````````````````
Expand Down
17 changes: 15 additions & 2 deletions lib/ansible/plugins/filter/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,22 @@ def ternary(value, true_val, false_val, none_val=None):
return false_val


def regex_escape(string):
def regex_escape(string, re_type='python'):
'''Escape all regular expressions special characters from STRING.'''
return re.escape(string)
if re_type == 'python':
return re.escape(string)
elif re_type == 'posix_basic':
# list of BRE special chars:
# https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions
return regex_replace(string, r'([].[^$*\\])', r'\\\1')
# TODO: implement posix_extended
# It's similar to, but different from python regex, which is similar to,
# but different from PCRE. It's possible that re.escape would work here.
# https://remram44.github.io/regex-cheatsheet/regex.html#programs
elif re_type == 'posix_extended':
raise AnsibleFilterError('Regex type (%s) not yet implemented' % re_type)
else:
raise AnsibleFilterError('Invalid regex type (%s)' % re_type)


def from_yaml(data):
Expand Down