【问题标题】:How to test jinja2 regex_replace ansible filters in python?如何在 python 中测试 jinja2 regex_replace ansible 过滤器?
【发布时间】:2022-11-08 19:54:23
【问题描述】:

让我们检查一下 regex_replace。它在我的 Ansible 剧本中有效,但在 ipython 中无效:

from jinja2 import Template
Template(" {{ zones | map('regex_replace', '(.*)', '\1') | join(',') }} ").render(zones=['z1','z2','z3'])

抛出: TemplateRuntimeError: No filter named 'regex_replace'.

第二次尝试:

from jinja2_ansible_filters.core_filters import regex_replace
env = jinja2.Environment()
env.filters["regex_replace"] = regex_replace

In [55]: env.from_string(" {{ zones | map('regex_replace', '(.*)', '\1') | join(',') }} ").render(zones=['z1','z2','z3'])
Out[55]: ' \x01\x01,\x01\x01,\x01\x01 '

谢谢,

【问题讨论】:

    标签: python ansible jinja2


    【解决方案1】:

    您的问题不是“如何在 python 中使用 jinja2 ansible 过滤器?”;您已经弄清楚了-您的第二个示例正在做正确的事情。您的问题特别与 regex_replace 模块有关,尤其是在替换字符串中使用反向引用。

    您的第一个问题只是基本的 Python 语法:当您在普通字符串中编写 时,这意味着“带有十六进制字符 0x01 的字节”。因此,您的 regex_replace 表达式将所有出现的 (.*) 替换为 0x01... 这解释了您的输出。好吧,部分;您还需要锚定您的正则表达式 (^(.*)$),否则它会匹配每行末尾的空字符串,导致替换次数是您预期的两倍。

    但回到反向引用......正确的语法是什么?一个问题是您的字符串将经过多个处理步骤;如果我们尝试显而易见的...

    "{{ zones | map('regex_replace', '^(.*)$', '\1') | join(',') }} "
    

    ...我们得到相同的输出。这表明我们只需要逃避足够多的时间来避免展开。事实证明这是有效的:

    "{{ zones | map('regex_replace', '^(.*)$', '\\1') | join(',') }} "
    

    我们可以通过使用原始字符串 (r"...") 来简化一些事情:

    r"{{ zones | map('regex_replace', '^(.*)$', '\1') | join(',') }} "
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多