2

I am looking at replacing multiple strings with input from the user. The following code (which is a modification of a code from one of the queries here in stackoverflow; pardon coz I can't find the thread anymore) works well when finding and replacing one instance(done on purpose) of a specified string:

print('What word should we replace s1 with?')
input_1 = input()
with open('C:\\dummy1.txt')as f:
     sample1 = f.read().replace("s1", str(input_1), 1)
with open('C:\\dummy2.txt',"w") as f1:
     f1.write(sample1)

Now when I try copy-pasting the same and modifying it to cater to other strings, only the last specified string gets replaced... here's a sample code:

print('What word should we replace s1 with?')
input_1 = input()
with open('C:\\dummy1.txt')as f:
     sample1 = f.read().replace("s1", str(input_1), 1)
with open('C:\\dummy2.txt',"w") as f1:
     f1.write(sample1)

print('What word should we replace s2 with?')
input_2 = input()
with open('C:\\dummy1.txt')as f:
     sample2 = f.read().replace("s2", str(input_2), 1)
with open('C:\\dummy2.txt',"w") as f1:
     f1.write(sample2)

What do I need to do to make this work seamlessly for multiple strings? Please consider explaining it to someone with less than a year experience in coding and 9-hour worth of video learning in python :) Thank you!

3
  • Is there a reason you don't get both inputs and then replace s1 and s2 at the same time so you aren't opening and closing more than needed? Commented Nov 1, 2017 at 14:41
  • That might do the trick! Now, how to? :) Commented Nov 1, 2017 at 14:44
  • I added an answer showing what I mean. Commented Nov 1, 2017 at 14:58

4 Answers 4

2

This worked for me.

#using os to get path since py and txt file are in same folder
#just change your actual path if you need
import os
curdir=os.getcwd()
filepath=os.path.join(curdir,'the_file.txt')


print('What word should we replace s1 with?')
input_1 = input()
print('What word should we replace s2 with?')
input_2 = input()

sample1=''
sample2=''
with open(filepath, 'r')as f:
     sample1 = f.read().replace("s1", str(input_1), 1)
     sample2 = sample1.replace("s2", str(input_2), 1)
with open(filepath, 'w')as f:    
     f.write(sample2)

EDIT:

Also I just realized than you read from dummy1.txt and write to dummy2.txt both times that you get inputs and replace text. That's the reason that only s2 is being changed. You should read from dummy2.txt when changing s2 because that is the file that contains the s1 change. In my example above I just overwrite the file I read from, but that's easily changed if you want.

    #using os to get path since py and txt file are in same folder
#just change your actual path if you need
import os
curdir=os.getcwd()
filepath=os.path.join(curdir,'the_file.txt')
filepath_2=os.path.join(curdir,'the_other_file.txt')


print('What word should we replace s1 with?')
input_1 = input()
print('What word should we replace s2 with?')
input_2 = input()

sample1=''
sample2=''
with open(filepath, 'r')as f:
     sample1 = f.read().replace("s1", str(input_1), 1)
     sample2 = sample1.replace("s2", str(input_2), 1)
with open(filepath_2, 'w')as f:    
     f.write(sample2)
Sign up to request clarification or add additional context in comments.

4 Comments

OMG, thank you! Just one minor issue, how do I get it to save as another file (renamed)? The original file will be used multiple times so it has to remain unchanged,.. sorry for the total noobishness haha
You can simply make a "filepath_2" or something, see edit
Ooops, I just figured it out. Thank you SuperStew :)
Your post comment sure is enlightening :)
0

I think what you want is, in the second instance, to open the file C:\\dummy2.txt file in append mode rather than write mode (which overwrites any previous output), e.g., use open('C:\\dummy2.txt',"a") rather than open('C:\\dummy2.txt',"w")

1 Comment

Thanks for answering, Matt. I appreciate it :)
0

For a shorter code, you could get both strings at once and chain the replace method:

replacement_strings = input('Please enter S1 and S2, separated by hyphen :').split('-')
with open('C:\\dummy1.txt')as f:
    sample1 = f.read().replace("s1", replacement_strings[0]).replace("s2", replacement_strings[1]) if len(replacement_strings) > 1 else f.read().replace("s1", replacement_strings[0]) if replacement_strings
with open('C:\\dummy2.txt',"w") as f1:
    f1.write(sample1)

Note: For python 2.x, you would need to use raw_input() instead of input()

2 Comments

Hey! This idea of putting all together in a single input is awesome! I could certainly use it but I fear this code is incomplete? PS: Would love to upvote but still can't coz <15 rep and stuff XD
Oh, I just deleted the if and else parts and it worked like a charm. Thanks a lot for this code, @TemiFakunle !
0

I found a way to easily find-replace multiple strings in Python.

In this example, find[0] is replaced by replace[0] etc.

The statement "x = line.replace(find[0], replace[0]).replace(find[1], replace[1])..." is dynamically created as a string, and later this string is executed.

I used this script transform a word docx into an HTML file and then change multiple strings in that HTML file.

import mammoth
import os
import fileinput    

#set source, output
source = 'test.docx'
output = 'output.html'    

#set find and replace, e.g. find[0] will be replaced by replace[0]
find = ['a', '1']
replace = ['b', '2']    

#convert to html in temp file
temp = '.temp.html'
f = open(source, 'rb')
b = open(temp, 'wb')
document = mammoth.convert_to_html(f)
b.write(document.value.encode('utf8'))
f.close()
b.close()    

#create a find-and-replace statement
i = 0
c = len(find)
string = "x = line"
while i < c: 
    x = ".replace(find[" + str(i) + "], replace[" + str(i) + "])"
    string = string + x
    i = i + 1    

#write output file
f = open(output, 'wb')
with fileinput.FileInput(temp, inplace=False, openhook=fileinput.hook_encoded('utf-8', 'surrogateescape')) as file:
    for line in file:
        #execute the find-and-replace statement
        exec(string)
        f.write(x.encode('utf-8'))
f.close()    

#remove temp file
os.remove(temp)

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.