如何替换字符串模板中的 NAME 之类的子字符串?

How to replace substrings like NAME in a string template?

我有一个包含我想要替换的子字符串的字符串,例如

text = "Dear NAME, it was nice to meet you on DATE. Hope to talk with you and SPOUSE again soon!"

我有一个 csv 格式(第一行是 header)

NAME, DATE, SPOUSE
John, October 1, Jane
Jane, September 30, John
...

我正在尝试遍历 csv 文件中的每一行,用 header 行与原始子字符串匹配的列中的 csv 元素替换 text 中的子字符串。我有一个名为 matchedfields 的列表,其中包含在 csv header 行和 text 中找到的所有字段(如果 csv 中有一些我不需要的列使用)。我的下一步是遍历每个 csv 行,并将匹配的字段替换为该 csv 列中的元素。为此,我使用

with open('recipients.csv') as csvfile:
 reader = csv.DictReader(csvfile)
 for row in reader:
     for match in matchedfields:
        print inputtext.replace(match, row[match])

我的问题是,这只会用 csv 中的适当元素替换 text 中第一个匹配的子字符串。有没有办法同时进行多个替换,所以我最终得到

"Dear John, it was nice to meet you on October 1. Hope to talk with you and Jane again soon!"

"Dear Jane, it was nice to meet you on September 30. Hope to talk with you and John again soon!"

您应该将替换后的字符串重新分配给原始名称,这样以前的替换就不会被丢弃:

with open('recipients.csv') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        inputtext = text
        for match in matchedfields:
            inputtext = inputtext.replace(match, row[match])
        print inputtext

另一方面,您可以使用 字符串格式 更新原始字符串,并对字符串稍作修改,如下所示:

text = "Dear {0[NAME]}, it was nice to meet you on {0[DATE]}. Hope to talk with you and {0[SPOUSE]} again soon!"

with open('recipients.csv') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        inputtext = text.format(row)
        print inputtext

使用字典一步格式化字符串,无需反复进行替换。

问题是 inputtext.replace(match, row[match]) 不会更改 inputtext 变量,它只是生成一个您没有存储的新字符串。试试这个:

import copy 

with open('recipients.csv') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        inputtext_copy = copy.copy(inputtext) ## make a new copy of the input_text to be changed.
        for match in matchedfields:
            inputtext_copy = inputtext_copy.replace(match, row[match]) ## this saves the text with the right 
        print inputtext ## should be the original w/ generic field names 
        print inputtext_copy ## should be the new version with all fields changed to specific instantiations

我认为真正的方法是使用字符串模板。让您的生活更轻松。

这是在 Python2 和 3 下工作的通用解决方案:

import string

template_text = string.Template(("Dear ${NAME}, "
                                 "it was nice to meet you on ${DATE}. "
                                 "Hope to talk with you and ${SPOUSE} again soon!"))

然后

import csv

with open('recipients.csv') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        print(template_text.safe_substitute(row))

现在,我注意到您的 csv 中有一些空格,因此您必须先解决这个问题(或者使调用适应 csv reader 或模板)。