Terraform |替换字符串中的多个子字符串

Terraform |替换字符串中的多个子字符串,terraform,terraform0.12+,Terraform,Terraform0.12+,我有一个字符串,其中有多个子字符串需要替换 字符串: string1=“我想明天坐飞机” 我需要从地图上取任何需要替换的东西 地图: map1 = { "I": "we" "want": "do not want" "tomorrow": "today" } 因此,map1map中的键是string1字符串中需要替换的键,这些值应该是字符串中的新值

我有一个字符串,其中有多个子字符串需要替换

字符串:
string1=“我想明天坐飞机”

我需要从地图上取任何需要替换的东西

地图:

map1 = {
    "I": "we"
    "want": "do not want"
    "tomorrow": "today"
  }
因此,
map1
map中的键是
string1
字符串中需要替换的键,这些值应该是字符串中的新值

结果应该如下所示:
我们今天不想坐飞机

我一直在想一个解决办法,但我还没有接近

我试过这个:

try = [for replacement in keys(local.map1): replace(local.string1, replacement, local.map1[replacement])]
但这将返回一个字符串列表,每个字符串只替换一个值


注意
string1
map1
只是示例,它们可能有任何其他值,因此我正在寻找一个通用解决方案,请:)

我想您可以这样做:

variable "string1" {
  default = "I want to fly tomorrow"
}

variable "map1" {
  default = {
    "I" = "we"
    "want" = "do not want"
    "tomorrow" = "today"
  }
}

output "test" {
  value = join(" ", [for word in split(" ", var.string1): lookup(var.map1, word, word)]) 
}
输出为:

we do not want to fly today

这是工作所需要的东西;这在地形0.12.23上进行了测试。与Marcin的回答不同的是,这适用于多个占位符(可能在同一行上),并且有多行

考虑到我们有一个带有
{}
格式占位符的文件,我需要用键/值对的映射来替换它们

以下是您可以复制/粘贴的内容

sample.txt

Hello {name}, my favorite food is {food} I'd
  like to eat {food} and sleep.
  Here's a {non_existent} variable
$ terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

test_out = Hello Data_sniffer, my favorite food is Sushi I'd
  like to eat Sushi and sleep.
  Here's a {non_existent} variable
操场。tf

locals {
  input = file("./sample.txt")

  map = {
    food = "Sushi"
    name = "Data_sniffer"
  }

  out = join("\n", [
    for line in split("\n", local.input) :
      format(
        replace(line, "/{(${join("|", keys(local.map))})}/", "%s"),
        [
          for value in flatten(regexall("{(${join("|", keys(local.map))})}", line)) :
            lookup(local.map, value)
        ]...
      )
  ])
}

output "test_out" {
  value = local.out
}
输出

Hello {name}, my favorite food is {food} I'd
  like to eat {food} and sleep.
  Here's a {non_existent} variable
$ terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

test_out = Hello Data_sniffer, my favorite food is Sushi I'd
  like to eat Sushi and sleep.
  Here's a {non_existent} variable

下面解释一下这种魔法是如何发挥作用的:

  • 第一步是用换行符分割文本,这样您就可以处理以下内容:

    [
    “你好{name},我最喜欢的食物是{food}I'd”,
    “喜欢吃{食物}和睡觉。”,
    “这是一个{不存在}变量”
    ]
    
  • 现在我们要替换占位符。然而,在撰写本文时,Terraform并没有一种简单的方法可以在一个字符串中轻松替换多个字符串。因此,我们将同时使用该函数;它的占位符需要
    %s
    。基本上,我们希望我们的阵列现在看起来像这样:

    [
    “你好%s,我最喜欢的食物是%s我想吃”,
    “喜欢吃%s和睡觉。”,
    “这是一个{不存在}变量”
    ]
    
    为了得到每一行的转换,我们想用
    %s
    替换有效的
    {}
    占位符;i、 我们不想替换地图中不存在的
    {non_-existence}

    我们利用Terraform允许您进行正则表达式替换的事实,因此我们需要以下正则表达式:
    {(食品|名称)}
    (其中
    食品
    名称
    是我们要替换的键)。由于我们不希望手动维护此列表,因此我们使用和以编程方式构建正则表达式

    现在我们有了一个正则表达式,我们可以使用,它支持正则表达式

    replace(line, "/{(${join("|", keys(local.map))})}/", "%s")
    
  • 但是等等!我们现在只有
    %s
    ,我们如何知道以什么顺序替换什么???这就是问题所在(不是
    regex()
    )。使用上面几乎相同的正则表达式,我们将再次拉出匹配的占位符

    (上面的正则表达式和这个正则表达式之间的唯一区别是开头和结尾缺少
    /

    此函数调用将返回找到的所有占位符。必须在此处使用
    regexall()
    all,否则它将在第一次匹配时停止

    [
    [
    “姓名”
    ],
    [
    “食物”
    ]
    ]
    
    这里不需要双重嵌套列表,所以我们将使用

    现在又回来了,

    [
    “姓名”,
    “食物”,
    ]
    
    现在,我们可以使用此列表通过函数从映射中查找相应的值

    [
      for value in flatten(regexall("{(${join("|", keys(local.map))})}", "Hello {name}, my favorite food is {food} I'd")) :
        lookup(local.map, value)
    ]
    
    返回:

    [
      "Data_sniffer",
      "Sushi",
    ]
    
    这个替换值数组可以被输入到我们的顶级
    format()
    调用中。但是,
    format()
    不接受需要逗号分隔参数的数组。因此,使用将列表展开为函数参数


  • 用于在字符串上迭代和使用
    查找
    根据需要替换或默认为原始元素的聪明算法。
    [
      "Data_sniffer",
      "Sushi",
    ]