5

I took example code from here.

f1 = open('file1.txt', 'r')
f2 = open('file2.txt', 'w')
for line in f1:
    f2.write(line.replace('old_text', 'new_text'))
f1.close()
f2.close()

But I am not able to figure out how to replace multiple words with respective new words. In this example if I want to find some words like (old_text1,old_text2,old_text3,old_text4) and replace by its respective new words (new_text1,new_text2,new_text3,new_text4).

Thanks in advance!

bikuser
  • 2,013
  • 4
  • 33
  • 57

5 Answers5

15

You can iterate over your check words and toReplace words using zip and then replace.

Ex:

checkWords = ("old_text1","old_text2","old_text3","old_text4")
repWords = ("new_text1","new_text2","new_text3","new_text4")

for line in f1:
    for check, rep in zip(checkWords, repWords):
        line = line.replace(check, rep)
    f2.write(line)
f1.close()
f2.close()
bikuser
  • 2,013
  • 4
  • 33
  • 57
Rakesh
  • 81,458
  • 17
  • 76
  • 113
  • 2
    This processes the file line-by-line, and may thus be very memory efficient for large files. It does have the drawback though, of not being able to replace words that span multiple lines, much like in a simple use of `sed`. – hoijui Sep 23 '20 at 05:12
  • Another issue: if you have replacements like `{"foo": "bar", "bar": "baz"}` then `"foo"` becomes `"baz"` rather than `"bar"`. Usually, you want all of these replacements done in one fell swoop rather than one at a time. – ggorlen Feb 23 '23 at 19:58
1

It's easy use re module

import re
s = "old_text1 old_text2"
s1 = re.sub("old_text" , "new_text" , s)

output

'new_text1 new_text2'

re.sub substitute the old text with the new text re.sub doc https://docs.python.org/3.7/library/re.html#re.sub

aman5319
  • 662
  • 5
  • 16
1
def replace_all(text, dic):
    for i, j in dic.iteritems():
        text = text.replace(i, j)
    return text

Our method, replace_all(), takes 2 arguments. The first one, text, is the string or file (it’s text) that the replacement will take place. The second one, dic, is a dictionary with our word or character(s) to be replaced as the key, and the replacement word or character(s) as the value of that key. This dictionary can have just one key:value pair if you want to replace just one word or character, or multiple key:values if you want to replace multiple words or characters at once.

Search and Replace multiple words or characters with Python

user9862376
  • 29
  • 10
1

I've learned that this script works very well and much faster then the ones that i've used in the past.

import re

def word_replace(text, replace_dict):
rc = re.compile(r"[A-Za-z_]\w*")

def translate(match):
    word = match.group(0).lower()
    print(word)
    return replace_dict.get(word, word)

return rc.sub(translate, text)

old_text = open('YOUR_FILE').read()

replace_dict = {
"old_word1" : 'new_word1',
"old_word2" : 'new_word2',
"old_word3" : 'new_word3',
"old_word4" : 'new_word4',
"old_word5" : 'new_word5'

 }                            # {"words_to_find" : 'word_to_replace'}

output = word_replace(old_text, replace_dict)
f = open("YOUR_FILE", 'w')                   #what file you want to write to
f.write(output)                              #write to the file
print(output)                                #check that it worked in the console 
john smith
  • 50
  • 16
1

You can replace the content of a text or file with sub from the regex module (re):

def replace_content(dict_replace, target):
    """Based on dict, replaces key with the value on the target."""

    for check, replacer in list(dict_replace.items()):
        target = sub(check, replacer, target)

    return target

Or just with str.replace which does not need from re import sub:

def replace_content(dict_replace, target):
    """Based on dict, replaces key with the value on the target."""

    for check, replacer in list(dict_replace.items()):
        target = target.replace(check, replacer)

    return target

Here's the full implementation:

from re import sub
from os.path import abspath, realpath, join, dirname

file = abspath(join(dirname(__file__), 'foo.txt'))
file_open = open(file, 'r')
file_read = file_open.read()
file_open.close()

new_file = abspath(join(dirname(__file__), 'bar.txt'))
new_file_open = open(new_file, 'w')


def replace_content(dict_replace, target):
    """Based on dict, replaces key with the value on the target."""

    for check, replacer in list(dict_replace.items()):
        target = sub(check, replacer, target)
        # target = target.replace(check, replacer)

    return target


# check : replacer
dict_replace = {
    'ipsum': 'XXXXXXX',
    'amet,': '***********',
    'dolor': '$$$$$'
}

new_content = replace_content(dict_replace, file_read)
new_file_open.write(new_content)
new_file_open.close()

# Test
print(file_read)
# Lorem ipsum dolor sit amet, lorem ipsum dolor sit amet

print(new_content)
# Lorem XXXXXXX $$$$$ sit *********** lorem XXXXXXX $$$$$ sit amet
Mr. T
  • 11,960
  • 10
  • 32
  • 54
Treedbox
  • 690
  • 7
  • 8
  • re.sub was previously suggested multiple times. What is different in your answer? – Mr. T Oct 27 '18 at 21:53
  • Hi **Mr.T**, I think the difference is the way of how to use a dict and convert it in a list **list(dict.items())** to replace multiple words and deliver a content that can be reused. – Treedbox Oct 27 '18 at 22:25