【发布时间】:2021-07-24 09:13:47
【问题描述】:
我有一个包含占位符的字典及其可能的值列表,如下所示:
{
"~GPE~": ['UK', 'USA'],
"~PERSON~": ['John Davies', 'Tom Banton', 'Joe Morgan'],
# and so on ...
}
我想通过替换模板中的占位符(即~GPE~ 和~PERSON~)来创建所有可能的字符串组合:
"My name is ~PERSON~. I travel to ~GPE~ with ~PERSON~ every year".
预期输出是:
"My name is John Davies. I travel to UK with Tom Banton every year."
"My name is John Davies. I travel to UK with Joe Morgan every year."
"My name is John Davies. I travel to USA with Tom Banton every year."
"My name is John Davies. I travel to USA with Joe Morgan every year."
"My name is Tom Banton. I travel to UK with John Davies every year."
"My name is Tom Banton. I travel to UK with Joe Morgan every year."
"My name is Tom Banton. I travel to USA with John Davies every year."
"My name is Tom Banton. I travel to USA with Joe Morgan every year."
"My name is Joe Morgan. I travel to UK with Tom Banton every year."
"My name is Joe Morgan. I travel to UK with John Davies every year."
"My name is Joe Morgan. I travel to USA with Tom Banton every year."
"My name is Joe Morgan. I travel to USA with John Davies every year."
还要注意字典中某个键对应的值如何在同一个句子中不重复。例如我不想:“我的名字是 Joe Morgan。我每年都和 Joe Morgan 一起去美国旅行。” (所以不完全是笛卡尔积,但足够接近)
我是 python 新手,正在尝试使用 re 模块,但找不到解决此问题的方法。
编辑
我面临的主要问题是替换字符串会导致长度发生变化,这使得后续修改字符串变得困难。这尤其是由于字符串中相同占位符的多个实例的可能性。下面是一个sn-p来详细说明:
label_dict = {
"~GPE~": ['UK', 'USA'],
"~PERSON~": ['John Davies', 'Tom Banton', 'Joe Morgan']
}
template = "My name is ~PERSON~. I travel to ~GPE~ with ~PERSON~ every year."
for label in label_dict.keys():
modified_string = template
offset = 0
for match in re.finditer(r'{}'.format(label), template):
for label_text in label_dict.get(label, []):
start, end = match.start() + offset, match.end() + offset
offset += (len(label_text) - (end - start))
# print ("Match was found at {start}-{end}: {match}".format(start = start, end = end, match = match.group()))
modified_string = modified_string[: start] + label_text + modified_string[end: ]
print(modified_string)
给出不正确的输出为:
My name is ~PERSON~. I travel to UK with ~PERSON~ every year.
My name is ~PERSON~. I travel USA with ~PERSON~ every year.
My name is John Davies. I travel to ~GPE~ with ~PERSON~ every year.
My name is JohTom Banton. I travel to ~GPE~ with ~PERSON~ every year.
My name is JohToJoe Morgan. I travel to ~GPE~ with ~PERSON~ every year.
My name is JohToJoe Morgan. I travel to ~GPE~ with John Davies every year.
My name is JohToJoe Morgan. I travel to ~GPE~ with JohTom Banton every year.
My name is JohToJoe Morgan. I travel to ~GPE~ with JohToJoe Morgan every year.
【问题讨论】:
-
@Tomalak 不,因为我不知道如何替换给定字符串中相同占位符的多个实例。例如“~GPE~”在模板中出现两次。使用 re.finditer 我可以处理占位符的多个实例,但是字符串的长度会在用可能的值替换占位符时发生变化。添加了 sn-p 以进一步详细说明。
-
正则表达式用于替换patterns。你没有模式。你有一个固定的字符串。您可以使用旧的
str.replace(),并且可以指示该函数仅替换 N(例如 1)个实例。 docs.python.org/3/library/stdtypes.html#str.replace -
我确实有模式。字典中的键是模式。挑战是用可能值中的唯一值替换模式/占位符的所有实例。
-
不,你没有。你有
"~GPE~"和"~PERSON~",它们是固定字符串。
标签: python-3.x string algorithm combinatorics python-re