summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Cassell <code@james.cassell.me>2019-03-07 14:51:19 +0100
committerSam Doran <sdoran@redhat.com>2019-03-07 14:51:19 +0100
commite55e8fe2c465a32d09fccf8de4f2aab25c7d6342 (patch)
tree56896913a36f6269a55be892be0e11a179c790e5
parenthttpapi/nxos_facts: raise ConnectionError is missing `code` (#53406) (diff)
downloadansible-e55e8fe2c465a32d09fccf8de4f2aab25c7d6342.tar.xz
ansible-e55e8fe2c465a32d09fccf8de4f2aab25c7d6342.zip
regex_escape: support POSIX basic regex (#50327)
-rw-r--r--changelogs/fragments/regex-escape-basic.yaml8
-rw-r--r--docs/docsite/rst/user_guide/playbooks_filters.rst9
-rw-r--r--lib/ansible/plugins/filter/core.py17
3 files changed, 31 insertions, 3 deletions
diff --git a/changelogs/fragments/regex-escape-basic.yaml b/changelogs/fragments/regex-escape-basic.yaml
new file mode 100644
index 0000000000..6732b9e8f4
--- /dev/null
+++ b/changelogs/fragments/regex-escape-basic.yaml
@@ -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.
diff --git a/docs/docsite/rst/user_guide/playbooks_filters.rst b/docs/docsite/rst/user_guide/playbooks_filters.rst
index ab0a5f3f18..6b55c0d48f 100644
--- a/docs/docsite/rst/user_guide/playbooks_filters.rst
+++ b/docs/docsite/rst/user_guide/playbooks_filters.rst
@@ -1075,11 +1075,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
``````````````````
diff --git a/lib/ansible/plugins/filter/core.py b/lib/ansible/plugins/filter/core.py
index 98885b2409..ac66dcdd97 100644
--- a/lib/ansible/plugins/filter/core.py
+++ b/lib/ansible/plugins/filter/core.py
@@ -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):