Search code examples
pythonstringreplacesplit

How to swap words in string including the punctuation (Python)?


I am trying to write a function, that will swap two already existing words.

Unfortunately, I have some problems with it. The main problem - punctuation. I know that when i'm trying to use split() method, it saves word in list like this: 'specialist,', and that's why i can't just use replce() method after using split().

So,i tried to use the answer from here, but it doesn't work for my case, and i don't know why.

When I try to swap words, for example specialist and software it returns something like this:

Sentence before changing: A programmer is a specialist, who develops software (in simpler cases, individual programs) for programmable devices.

Changed sentence: A programmer is a specialist, who develops specialist (in simpler cases, individual programs) for programmable devices.

And the second problem - you can use any word (even there is no such word in the string) when you calling the function, and it doesn't return any erorr. I think it shouldn't work like this.

My swap_words.py:

from string import punctuation


def swap_words(user_string, word_1, word_2):
    """Function for swapping words in string"""
    print(f"\nSentence before changing: {user_string}")
    listed_string = user_string.split()
    for i, word in enumerate(listed_string):
        if word == word_1:
            if word[-1] in punctuation:
                listed_string[i] = word_2 + word_1[-1]
            else:
                listed_string[i] = word_2
        elif word == word_2:
            if word[-1] in punctuation:
                listed_string[i] = word_1 + word_2[-1]
            else:
                listed_string[i] = word_1
    changed_string = ' '.join(listed_string)
    print(f"Changed sentence: {changed_string}")


sentence = "A programmer is a specialist, who develops software (in simpler " \
           "cases, individual programs) for programmable devices."

swap_words(sentence, 'specialist', 'software')

So, what i need to do?

Related question - here.


Solution

  • this hope help you It's kind of

    1. you cna use any word
    2. use "re", can ingore punctuation

    Disadvantages: Slow performance in extreme cases

    Use Case

    swap_words(sentence, 'programs', 'devices')
    Sentence before changing: A programmer is a specialist, who develops software (in simpler cases, individual programs) for programmable devices.
    Changed sentence:         A programmer is a specialist, who develops software (in simpler cases, individual devices) for programmable programs.
    
    
    swap_words(sentence, 'in', 'devices')
    Sentence before changing: A programmer is a specialist, who develops software (in simpler cases, individual programs) for programmable devices.
    Changed sentence:         A programmer is a specialist, who develops software (devices simpler cases, individual programs) for programmable in.
    
    swap_words(sentence, 'software', 'specialist')
    Sentence before changing: A programmer is a specialist, who develops software (in simpler cases, individual programs) for programmable devices.
    Changed sentence:         A programmer is a software, who develops specialist (in simpler cases, individual programs) for programmable devices.
    
    
    swap_words(sentence, 'A', 'specialist')
    Sentence before changing: A programmer is a specialist, who develops software (in simpler cases, individual programs) for programmable devices.
    Changed sentence:         specialist programmer is a A, who develops software (in simpler cases, individual programs) for programmable devices.
    
    
    import re
    from string import punctuation
    
    def findall_re_index(user_string: str, word_1, word_2):
        """
        在user_string中搜索word_1的正则匹配,组成匹配索引
        :param user_string:
        :param word_1:
        :param word_2:
        :return:
        """
        index_result = []
        while len(user_string) > 0:
            search_result = re.search(
                f"^{word_1}[{punctuation}\s]|[{punctuation}\s]{word_1}[{punctuation}\s]|[{punctuation}\s]{word_1}$",
                user_string)
            if not search_result:
                break
            search_index = list(search_result.span())
            # 在索引 search_index中,未来会执行操作 word_1替换成word_2
            index_result.append(search_index + [word_1, word_2])
            user_string = user_string[search_index[1]:]
        return index_result
    
    
    def replace_index(user_string: str, search_index_list: list[list]) -> str:
        """
        replace str by search index list
        :param user_string: The string to be replaced
        :param search_index_list: replace index list
        :return: replaced string
        """
        for index in search_index_list:
            start = index[0]
            end = index[1]
            word_1 = index[2]
            word_2 = index[3]
            user_string = user_string[:start] + user_string[start:end].replace(word_1, word_2) + user_string[end:]
        return user_string
    
    
    def swap_words(user_string, word_1, word_2):
        """Function for swapping words in string"""
        print(f"Sentence before changing: {user_string}")
    
        search_word_1 = findall_re_index(user_string, word_1, word_2)
        search_word_2 = findall_re_index(user_string, word_2, word_1)
        if not search_word_2 or not search_word_1:
            print("not changed")
            return
    
        sorted_search_word_index = sorted(search_word_1 + search_word_2, key=lambda x: x[0], reverse=True)
        changed_string = replace_index(user_string, sorted_search_word_index)
        print(f"Changed sentence:         {changed_string}")