【问题标题】:Disable metacharacters in regular expressions禁用正则表达式中的元字符
【发布时间】:2022-01-17 16:37:50
【问题描述】:

Perl 在其正则表达式工具包中有\Q and \E operators

"Foo (bar)" =~ /Foo \Q(bar)\E/; # Yup
"Foo (bar)" =~ /Fo. \Q(bar)\E/; # Yup
"Foo (bar)" =~ /Fo. \Q(ba.)\E/; # Nope

Python 中是否存在这样的工具?我知道 in 运算符可以进行文字字符串比较,但我的用例是我使用的是 lineinfile Ansible 模块,它依赖于 Python 的正则表达式库。我想要这样的东西(如果你能看到意图,即使这不起作用):

- lineinfile:
    path: /somewhere/over/the/rainbow
    regexp: "^\Q{{ item }}\E$"
    line: "{{ item }}"
  loop: "{{ some_list }}"

我也知道“search_string”,但我们目前正在运行不支持此功能的 Ansible 2.9。

【问题讨论】:

  • 可以使用re.escape()函数。
  • Ansible 2.8 it's about time to upgrade
  • 我已经更新了原始问题以将 2.8 替换为 2.9,这实际上是我们使用的。我们使用 Debian 打包版本的 Ansible,因此最终“使用 2.11”将是一个可行的答案,但暂时不会。
  • 我看不到如何将 re.escape() 工作到 Ansible 游戏中。我会考虑的。

标签: python regex ansible


【解决方案1】:

试试过滤器regex_escape,例如

    - lineinfile:
        path: test.txt
        regexp: "^{{ item|regex_escape }}$"
        line: "{{ item }}"
      loop:
        - '^f.*o(.*)$'

给予

shell> cat test.txt
^f.*o(.*)$

下面是 Perl 示例的 Ansible(Python) 等价物

shell> cat test.yml
---
- hosts: localhost
  tasks:
    - lineinfile:
        path: test.txt
        regexp: "^{{ item.regexp }}$"
        line: "{{ item.line }}"
      loop:
        - {line: 'Foo (bar)', regexp: "{{ 'Foo ' ~ '(bar)'|regex_escape }}"}
        - {line: 'Foo (bar)', regexp: "{{ 'Fo. ' ~ '(bar)'|regex_escape }}"}
        - {line: 'Foo (bar)', regexp: "{{ 'Fo. ' ~ '(ba.)'|regex_escape }}"}

在检查和差异模式下对空的 test.txt 文件运行 playbook 给出

shell> ansible-playbook test.yml -CD

PLAY [localhost] ***************************************************

TASK [lineinfile] **************************************************
--- before: test.txt (content)
+++ after: test.txt (content)
@@ -0,0 +1 @@
+Foo (bar)

changed: [localhost] => (item={'line': 'Foo (bar)', 'regexp': 'Foo \\(bar\\)'})
--- before: test.txt (content)
+++ after: test.txt (content)
@@ -0,0 +1 @@
+Foo (bar)

changed: [localhost] => (item={'line': 'Foo (bar)', 'regexp': 'Fo. \\(bar\\)'})
--- before: test.txt (content)
+++ after: test.txt (content)
@@ -0,0 +1 @@
+Foo (bar)

changed: [localhost] => (item={'line': 'Foo (bar)', 'regexp': 'Fo. \\(ba\\.\\)'})

尽管 regexp 不匹配,但列表中的第三项也被报告已更改。引用模块 lineinfile 参数regexp:“如果正则表达式不匹配,该行将被添加到文件中......

任务是幂等的。如果文件中存在该行

shell> cat test.txt
Foo (bar)

没有变化

TASK [lineinfile] **************************************************
ok: [localhost] => (item={'line': 'Foo (bar)', 'regexp': 'Foo \\(bar\\)'})
ok: [localhost] => (item={'line': 'Foo (bar)', 'regexp': 'Fo. \\(bar\\)'})
ok: [localhost] => (item={'line': 'Foo (bar)', 'regexp': 'Fo. \\(ba\\.\\)'})

【讨论】:

    猜你喜欢
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 2017-03-12
    • 2017-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多