ansible正则表达式替换所有匹配的string1,排除string2

时间:2019-05-18 22:11:13

标签: python regex ansible

我想将dogs的所有实例替换为cats,但行中带有does not play with mice的实例除外。

我的文件内容如下:

dogs:plays with mice
dogs:plays with mice
dogs:does not play with mice
dogs:plays with mice
dogs:plays with mice
dogs:does not play with mice
dogs:plays with mice

下面是我的ansible-playbook的重要部分,以尝试达到预期的效果:

  vars:
    file_to_update: /tmp/cats_dogs_file.txt
    exclude: "does not play with mice"
    from_name: "dogs"
    to_name: "cats"

  tasks:    

  - name: updates dogs to cats - excluding the necessary
    replace:
      path: "{{ file_to_update }}"
      regexp: "^{{ from_name }}(?! {{ exclude }})"
      replace: "{{ to_name }}"
    register: file_update_status

我希望文件内容按照以下内容进行更改:

cats:plays with mice
cats:plays with mice
dogs:does not play with mice
cats:plays with mice
cats:plays with mice
dogs:does not play with mice
cats:plays with mice

相反,我目前将所有dogs更改为cats

排除规则未得到遵守。

2 个答案:

答案 0 :(得分:1)

也许,在这里我们可以编写一个表达式,找到所需输出的部分并替换它们。也许类似于:

(.+):(plays? with)\s(.+)

enter image description here

JavaScript演示

const regex = /(.+):(plays? with)\s(.+)/gm;
const str = `dogs:plays with mice
dogs:plays with mice
dogs:does not play with mice
dogs:plays with mice
dogs:plays with mice
dogs:does not play with mice
dogs:plays with mice

cats:plays with mice
cats:plays with mice
dogs:does not play with mice
cats:plays with mice
cats:plays with mice
dogs:does not play with mice
cats:plays with mice`;
const subst = `cats:$2 $3`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

Python测试

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"(.+):(plays? with)\s(.+)"

test_str = ("dogs:plays with mice\n"
    "dogs:plays with mice\n"
    "dogs:does not play with mice\n"
    "dogs:plays with mice\n"
    "dogs:plays with mice\n"
    "dogs:does not play with mice\n"
    "dogs:plays with mice\n\n"
    "cats:plays with mice\n"
    "cats:plays with mice\n"
    "dogs:does not play with mice\n"
    "cats:plays with mice\n"
    "cats:plays with mice\n"
    "dogs:does not play with mice\n"
    "cats:plays with mice")

subst = "cats:\\2 \\3"

# You can manually specify the number of replacements by changing the 4th argument
result = re.sub(regex, subst, test_str, 0, re.MULTILINE)

if result:
    print (result)

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

RegEx

如果这不是您想要的表达式,则可以在regex101.com中修改/更改表达式。

RegEx电路

您还可以在jex.im中可视化您的表达式:

enter image description here

答案 1 :(得分:1)

一种简单的解决方案是遍历所有行,并有条件地排除不应替换的行。

下面的戏

tasks:
  - replace:
      path: "{{ file_to_update }}"
      regexp: "{{ item }}"
      replace: "{{ item|regex_replace(from_name, to_name) }}"
    with_lines: "cat {{ file_to_update }}"
    when: exclude not in item

给予(节略):

TASK [replace] 
******************************************************************************
changed: [localhost] => (item=dogs:plays with mice)
ok: [localhost] => (item=dogs:plays with mice)
skipping: [localhost] => (item=dogs:does not play with mice) 
ok: [localhost] => (item=dogs:plays with mice)
ok: [localhost] => (item=dogs:plays with mice)
skipping: [localhost] => (item=dogs:does not play with mice) 
ok: [localhost] => (item=dogs:plays with mice)

> cat cats_dogs_file.txt
cats:plays with mice
cats:plays with mice
dogs:does not play with mice
cats:plays with mice
cats:plays with mice
dogs:does not play with mice
cats:plays with mice