Home > Software engineering >  Reverse string without non letters symbol
Reverse string without non letters symbol

Time:03-29

I need to reverse only letters in each word. The order of the words and non-letter symbols must remain in their positions. I have a function, but it changes the position of the word.

def reverse_string(st):
    stack = []
    for el in st:
        if el.isalpha():
            stack.append(el)
    result = ''
    for el in st:
        if el.isalpha():
            result  = stack.pop()
        else:
            result  = el
    return result

Input string:

b3ghcd hg#tyj%h

Expected output string:

d3chgb hj#ytg%h

CodePudding user response:

You were really close! Your code is not working because you are applying the reversion to the whole string instead of doing it one word at a time. But just adding an extra step that splits the input string at white spaces (I assume white spaces is what defines words in your input) you'll get your desired result:

def reverse_string(st):
    return ' '.join(reverse_word(word) for word in st.split())

def reverse_word(st):
    stack = []
    for el in st:
        if el.isalpha():
            stack.append(el)
    result = ''
    for el in st:
        if el.isalpha():
            result  = stack.pop()
        else:
            result  = el
    return result

instr = 'b3ghcd hg#tyj%h'

print(reverse_string(instr)) # prints 'd3chgb hj#ytg%h'

NOTE: You can pythonify your code a bit using some built in functions of list comprehension. In this case you'd replace the building of your stack.

stack = []
    for el in st:
        if el.isalpha():
            stack.append(el)

for one of the following:

stack = [el for el in st if el.isalpha()] or stack = list(filter(str.isalpha, st))

CodePudding user response:

Using the function you provided, one way of doing it is:

import re

def reverse_word(st):
    stack = []
    for el in st:
        if el.isalpha():
            stack.append(el)
    result = ''
    for el in st:
        if el.isalpha():
            result  = stack.pop()
        else:
            result  = el
    return result

def reverse_string(st):
    return re.sub(r'\S ', lambda match: reverse_word(match.group()), st)

print(reverse_string("b3ghcd hg#tyj%h"))
# "d3chgb hj#ytg%h"

Not thoroughly tested, and you might want to use for example [^\s,.?!;] or similar instead of \S, depending on what kind of 'sentences' you are dealing with.

  • Related