how to delete char after -> without using a regular expression

Strings do not support item deletion. You have to create a new string.

>>> astring = 'abc->def'
>>> astring.index('->')  # Look at the index of the target string
3
>>> x=3
>>> astring[x:x+3]  # Here is the slice you want to remove
'->d'
>>> astring[0:x] + astring[x+3:]  # Here is a copy of the string before and after, but not including the slice
'abcef'

This only handles one '->' per string, but you can iterate on it.


Here's a simple recursive solution-

# Constant storing the length of the arrow
ARROW_LEN = len('->')

def delete_forward(s: str):
    try:
        first_occurence = s.index('->')
    except ValueError:
        # No more arrows in string
        return s
    if s[first_occurence + ARROW_LEN:first_occurence + ARROW_LEN + ARROW_LEN] == '->':
        # Don't delete part of the next arrow
        next_s = s[first_occurence + ARROW_LEN:]
    else:
        # Delete the character immediately following the arrow
        next_s = s[first_occurence + ARROW_LEN + 1:]
    return delete_forward(s[:first_occurence] + s[first_occurence + ARROW_LEN + 1:])

Remember, python strings are immutable so you should instead rely on string slicing to create new strings as you go.

In each recursion step, the first index of -> is located and everything before this is extracted out. Then, check if there's another -> immediately following the current location - if there is, don't delete the next character and call delete_forward with everything after the first occurrence. If what is immediately followed is not an arrow, delete the immediately next character after the current arrow, and feed it into delete_forward.

This will turn x->zb into xb.

The base case for the recursion is when .index finds no matches, in which case the result string is returned.

Output

>>> delete_forward('ab->cz')        
'abz'
>>> delete_forward('abcz')   
'abcz'
>>> delete_forward('->abc->z')
'bc'
>>> delete_forward('abc->z->')   
'abc'
>>> delete_forward('a-->b>x-->c>de->f->->g->->->->->')
'a->x->de'

There could be several methods to achieve this in python e.g.:

Using split and list comprehensions (If you want to delete a single character everytime one or more delete characters encountered):

def delete_forward(s):
    return ''.join([s.split('->')[0]] + [i[1:] if len(i)>1 else "" for i in s.split('->')[1:]])

Now delete_forward("a->bcz") returns 'acz' & delete_forward("->x->z") returns ''. ote that this works for EVERY possible case whether there are many delete characters, one or none at all. Moreover it will NEVER throw any exception or error as long as input is str. This however assumes you want to delete a single character everytime one or more delete characters encountered.

If you want to delete as many characters as the number of times delete characters occur:

def delete_forward(s):
    new_str =''
    start = 0
    for end in [i for i in range(len(s)) if s.startswith('->', i)] +[len(s)+1]:
        new_str += s[start:end]
        count = 0
        start = max(start, end)
        while s[start:start+2] =='->':
            count+=1
            start+=2
        start += count
    return new_str

This produces same output for above two cases however for case: 'a->->bc', it produces 'a' instead of 'ac' as produced by first function.

Tags:

Python