地形 |替换字符串中的多个子字符串
Terraform | Replacing multiple substrings in a string
我有一个字符串,其中有多个子字符串需要替换。
字符串:
string1 = "I want to fly tomorrow"
我需要从地图上取走任何需要更换的东西。
地图:
map1 = {
"I": "we"
"want": "do not want"
"tomorrow": "today"
}
因此 map1
映射中的键是 string1
字符串中需要替换的键,值应该是字符串中的新值。
结果应该是这样的:
we do not want to fly today
我一直在想一个解决方案,但我什至没有接近。
我试过这个:
try = [for replacement in keys(local.map1): replace(local.string1, replacement, local.map1[replacement])]
但是这个 returns 一个字符串列表,每个字符串只替换了一个值。
注意: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
这是工作需要的东西;这是在 Terraform 0.12.23 上测试的。与 Marcin 的回答不同,因为这适用于彼此相邻、字符之间(例如引号)或不被空格分隔的占位符。
鉴于我们有一个包含 {}
格式占位符的文件,我需要将它们替换为 key/value 对的映射。
这是您可以做到的 copy/paste。
sample.txt
Hello {name}, my favorite food is {food} I'd
like to eat {food} and sleep.
Here's a {non_existent} variable
playground.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
}
输出
$ 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
这里解释一下这个魔法是如何工作的:
第一步是用换行符分割你的文本,这样你就可以使用以下内容:
[
"Hello {name}, my favorite food is {food} I'd",
" like to eat {food} and sleep.",
" Here's a {non_existent} variable"
]
现在我们要替换我们的占位符。但是,在撰写本文时,Terraform 没有一种简单的方法可以轻松地在一个字符串中替换多个字符串。所以我们同时使用 format
函数;它的占位符需要 %s
。基本上,我们希望我们的数组现在看起来像这样:
[
"Hello %s, my favorite food is %s I'd",
" like to eat %s and sleep.",
" Here's a {non_existent} variable"
]
为了对每一行进行这种转换,我们想用 %s
替换有效的 {}
占位符;即我们不想替换地图中不存在的 {non_existent}
。
我们利用 Terraform 允许您进行正则表达式替换这一事实,因此我们需要以下正则表达式:{(food|name)}
(其中 food
和 name
是我们想换)。由于我们不想手动维护此列表,因此我们使用 keys()
and string interpolation.
以编程方式构建正则表达式
"/{(${join("|", keys(local.map))})}/"
现在我们有了正则表达式,我们可以使用 replace
,它支持正则表达式。
replace(line, "/{(${join("|", keys(local.map))})}/", "%s")
但是等等!我们现在只有 %s
,我们怎么知道要按什么顺序替换什么???这就是 regexall()
的用武之地( 而不是 regex()
)。使用上面 almost 相同的正则表达式,我们将再次提取匹配的占位符。
(上面的正则表达式和这个的唯一区别是开头和结尾缺少 /
)
regexall("{(${join("|", keys(local.map))})}", "Hello {name}, my favorite food is {food} I'd")
此函数调用将 return 我们找到的所有占位符。在这里使用 regexall()
很重要,否则它会在第一场比赛中停止。
[
[
"name"
],
[
"food"
]
]
我们这里不需要双重嵌套列表,所以我们将使用 flatten()
。
flatten(
regexall("{(${join("|", keys(local.map))})}", "Hello {name}, my favorite food is {food} I'd")
)
现在 return,
[
"name",
"food",
]
现在,我们可以使用这个 列表,通过lookup()
函数从地图中查找相应的值。
[
for value in flatten(regexall("{(${join("|", keys(local.map))})}", "Hello {name}, my favorite food is {food} I'd")) :
lookup(local.map, value)
]
哪个 returns:
[
"Data_sniffer",
"Sushi",
]
然后可以将此替换值数组输入到我们的顶级 format()
调用中。但是,format()
不接受它期望以逗号分隔的参数的数组。所以使用 ...
operator 将列表扩展为函数参数。
我有一个字符串,其中有多个子字符串需要替换。
字符串:
string1 = "I want to fly tomorrow"
我需要从地图上取走任何需要更换的东西。
地图:
map1 = {
"I": "we"
"want": "do not want"
"tomorrow": "today"
}
因此 map1
映射中的键是 string1
字符串中需要替换的键,值应该是字符串中的新值。
结果应该是这样的:
we do not want to fly today
我一直在想一个解决方案,但我什至没有接近。
我试过这个:
try = [for replacement in keys(local.map1): replace(local.string1, replacement, local.map1[replacement])]
但是这个 returns 一个字符串列表,每个字符串只替换了一个值。
注意: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
这是工作需要的东西;这是在 Terraform 0.12.23 上测试的。与 Marcin 的回答不同,因为这适用于彼此相邻、字符之间(例如引号)或不被空格分隔的占位符。
鉴于我们有一个包含 {}
格式占位符的文件,我需要将它们替换为 key/value 对的映射。
这是您可以做到的 copy/paste。
sample.txt
Hello {name}, my favorite food is {food} I'd
like to eat {food} and sleep.
Here's a {non_existent} variable
playground.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
}
输出
$ 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
这里解释一下这个魔法是如何工作的:
第一步是用换行符分割你的文本,这样你就可以使用以下内容:
[ "Hello {name}, my favorite food is {food} I'd", " like to eat {food} and sleep.", " Here's a {non_existent} variable" ]
现在我们要替换我们的占位符。但是,在撰写本文时,Terraform 没有一种简单的方法可以轻松地在一个字符串中替换多个字符串。所以我们同时使用
format
函数;它的占位符需要%s
。基本上,我们希望我们的数组现在看起来像这样:[ "Hello %s, my favorite food is %s I'd", " like to eat %s and sleep.", " Here's a {non_existent} variable" ]
为了对每一行进行这种转换,我们想用
%s
替换有效的{}
占位符;即我们不想替换地图中不存在的{non_existent}
。我们利用 Terraform 允许您进行正则表达式替换这一事实,因此我们需要以下正则表达式:
以编程方式构建正则表达式{(food|name)}
(其中food
和name
是我们想换)。由于我们不想手动维护此列表,因此我们使用keys()
and string interpolation."/{(${join("|", keys(local.map))})}/"
现在我们有了正则表达式,我们可以使用
replace
,它支持正则表达式。replace(line, "/{(${join("|", keys(local.map))})}/", "%s")
但是等等!我们现在只有
%s
,我们怎么知道要按什么顺序替换什么???这就是regexall()
的用武之地( 而不是regex()
)。使用上面 almost 相同的正则表达式,我们将再次提取匹配的占位符。(上面的正则表达式和这个的唯一区别是开头和结尾缺少
/
)regexall("{(${join("|", keys(local.map))})}", "Hello {name}, my favorite food is {food} I'd")
此函数调用将 return 我们找到的所有占位符。在这里使用
regexall()
很重要,否则它会在第一场比赛中停止。[ [ "name" ], [ "food" ] ]
我们这里不需要双重嵌套列表,所以我们将使用
flatten()
。flatten( regexall("{(${join("|", keys(local.map))})}", "Hello {name}, my favorite food is {food} I'd") )
现在 return,
[ "name", "food", ]
现在,我们可以使用这个 列表,通过
lookup()
函数从地图中查找相应的值。[ for value in flatten(regexall("{(${join("|", keys(local.map))})}", "Hello {name}, my favorite food is {food} I'd")) : lookup(local.map, value) ]
哪个 returns:
[ "Data_sniffer", "Sushi", ]
然后可以将此替换值数组输入到我们的顶级
format()
调用中。但是,format()
不接受它期望以逗号分隔的参数的数组。所以使用...
operator 将列表扩展为函数参数。