[SOLVED] Python replace whole words without using regex

Issue

I am wanting to replace whole words with another string without using regex. The replace_all_whole_words1 does what I want, but I don’t want to use regex and is only being used to test if my replace_all_whole_words2 function is working correctly (it isn’t).

import re
def replace_all_whole_words1(needle, replacement, haystack):
    needle = re.escape(needle)
    return re.sub(r"\b%s\b" % needle, replacement, haystack)

def replace_all_whole_words2(needle, replacement, haystack):
    i=0
    while len(haystack) > i:
        found_word = False
        found_word_start = i
        found_word_end = 0
        found_type = 0 # will repersent if we found,  word + " " or " " + word or " " + word + " " ()
        if i == 0:
            found_word = haystack[i:i+len(needle + " " )] == needle + " "
            found_word_end = i + len(needle) 
            found_type = 1
        elif i == len(haystack) - len(" " + needle):
            found_word = haystack[i:i+len(" " + needle)] == " " + needle
            found_word_end = i + len(" " + needle)
            found_type = 2
        else:
            found_word = haystack[i:i+len(" "  + needle + " " )] == " "  + needle + " "
            found_word_end = i + len(" " + needle + " ")
            found_type = 3
        if found_word:
            print(haystack, found_word_start, found_word_end, i, found_type)
            haystack = haystack[:found_word_start] + replacement + haystack[found_word_end:]

        i += 1
    return haystack



needle = "test"
replacement = "replaced"
haystack = "test test test testa atest"

print(
    replace_all_whole_words1(needle, replacement, haystack) == replace_all_whole_words2(needle, replacement, haystack)
)

print(
    replace_all_whole_words2(needle, replacement, haystack)
)

Solution

There are a couple of great and simpler answers here already that convert haystack to a list, perform the replacement and then convert it back to a string. If you still want to use haystack as a string throughout, check out this solution I made.

def replace_all_whole_words2(needle, replacement, haystack):
    # Counter to go through characters in haystack
    i = 0 
    
    # This will collect all chars separated by space as word
    word = '' 
    
    # len_needle will control replacement insertion and diff will adjust i after insertion 
    len_needle = len(needle)
    diff = len(replacement) - len_needle
    
    # Go through characters in haystack and replace needle with replacement
    while i < len(haystack):
        char = haystack[i]
        if char == ' ':
            if word == needle:
                haystack = haystack[:(i-len_needle)] + replacement + haystack[i:]
                
                # Adjust i so that you can continue from the next char after the space
                i += diff
                
            # Reset word to collect new chars
            word = ''
        else:
            word += char
        
        i += 1
        
    return haystack

Test:

needle = "test"
replacement = "replacement"
haystack = "test test test testa atest"

replace_all_whole_words2(needle, replacement, haystack)

Output:

'replacement replacement replacement testa atest'

Answered By – Emmanuel

Answer Checked By – David Marino (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *