2

I've got a string containing substrings I'd like to replace, e.g.

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

I've got a csv of the format (first row is a header)

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

I'm trying to loop through each row in the csv file, replacing substrings in text with the csv element from the column with header row matching the original substring. I've got a list called matchedfields which contains all the fields that are found in the csv header row and text (in case there are some columns in the csv I don't need to use). My next step is to iterate through each csv row and replace the matched fields with the element from that csv column. To accomplish this, I'm using

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

My problem is that this only replaces the first matched substring in text with the appropriate element from the csv. Is there a way to make multiple replacements simultaneously so I end up with

"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!"

3 Answers 3

8

I think the real way to go here is to use string templates. Makes your life easy.

Here is a general solution that works under Python2 and 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!"))

And then

import csv

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

Now, I noticed that your csv is kind of messed up with whitespaces, so you'll have to take care of that first (or adapt the call to either the csv reader or the template).

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent. string.safe_substitute() Never knew about Template strings (added back in Python 2.4)
3

The problem is that inputtext.replace(match, row[match]) doesn't change the inputtext variable, it just makes a new string that you aren't storing. Try this:

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

Comments

2

You should reassign the replaced string to the original name so the previous replacements are not thrown away:

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

On another note, you could update the original string using string formatting with a little modification to the string like so:

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

That formats the string with the dictionary in one step, without having to make replacements iteratively.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.