1

How can i remove only the last bracket from a string ?

For example, INPUT 1:

"hell(h)o(world)" 

i want this result:

"hell(h)o"

Input 2 :-

hel(lo(wor)ld)

i want :-

hel

as you can see the middle brackets remain intact only the last bracket got removed.

I tried :-

import re
string = 'hell(h)o(world)' 
print(re.sub('[()]', '', string))

output :-

hellhoworld

i figured out a solution :-

i did it like this

string = 'hell(h)o(world)' 
if (string[-1] == ")"):
    add=int(string.rfind('(', 0))
    print(string[:add])

output :-

hell(h)o

looking for other optimised solutions/suggestions..

8
  • Please clarify your problem. Your code above seems aimed at removing either a bracket or a parenthesis. You also state that you want to remove the matching left enclosure. What do you want to do with nested enclosures, such as hel(lo(wor)ld) ? As others have noted, posting your attempt as an answer is inappropriate, especially as you've found it unsatisfying.
    – Prune
    Commented Jul 16, 2021 at 18:07
  • @Prune thanks for the above comment in case of "hel(lo(wor)ld)" it will be "hel" since i want to remove the last bracket nested one will go along with it. Commented Jul 16, 2021 at 18:22
  • What about this "hell(h)o(world)blahblahblah" what is your output?
    – user16310106
    Commented Jul 16, 2021 at 18:23
  • @Hamzawi in case of "hell(h)o(world)blahblahblah" it will be "hell(h)oblahblahblah" Commented Jul 16, 2021 at 18:24
  • Your code fails with this example and returns "hel(lo" , right?
    – user16310106
    Commented Jul 16, 2021 at 18:26

4 Answers 4

2

Please see the below if this is useful, Let me know I will optimize further.

string = 'hell(h)o(world)'
count=0
r=''
for i in reversed(string):
    if count <2 and (i == ')' or i=='('):
        count+=1
        pass
    else:
        r+=i
for i in reversed(r):
    print(i, end='')
2
  • the above code is not giving any output to me. Commented Jul 16, 2021 at 18:26
  • Hey Rahul, Where do you find error. I hope this should work. let me know the error will help you out Commented Jul 17, 2021 at 9:38
2

If you want to remove the last bracket from the string even if it's not at the end of the string, you can try something like this. This will only work if you know you have a substring beginning and ending with parentheses somewhere in the string, so you may want to implement some sort of check for that. You will also need to modify if you are dealing with nested parenthesis.

str = "hell(h)o(world)"
r_str = str[::-1]    # creates reverse copy of string
for i in range(len(str)):
    if r_str[i] == ")":
        start = i
    elif r_str[i] == "(":
        end = i+1
        break
x = r_str[start:end][::-1]    # substring that we want to remove
str = str.replace(x,'')
print(str)

output:

hell(h)o

If the string is not at the end:

str = "hell(h)o(world)blahblahblah"

output:

hell(h)oblahblahblah

Edit: Here is a modified version to detect nested parenthesis. However, please keep in mind that this will not work if there are unbalanced parenthesis in the string.

str = "hell(h)o(w(orld))"
r_str = str[::-1]
p_count = 0
for i in range(len(str)):
    if r_str[i] == ")":
        if p_count == 0:
            start = i
        p_count = p_count+1
    elif r_str[i] == "(":
        if p_count == 1:
            end = i+1
            break
        else:
            p_count = p_count - 1
x = r_str[start:end][::-1]
print("x:", x)
str = str.replace(x,'')
print(str)

output:

hell(h)o

1
  • hello @jbowen4 for "hell(h)o(w(orld))" it is giving me "hell(h)o(w)" but i want something like "hell(h)o" Commented Jul 16, 2021 at 18:30
2

Something like this?

string = 'hell(h)o(w(orl)d)23'
new_str = ''
escaped = 0
for char in reversed(string):
    if escaped is not None and char == ')':
        escaped += 1

    if not escaped:
        new_str = char + new_str

    if escaped is not None and char == '(':
        escaped -= 1
        if escaped == 0:
            escaped = None

print(new_str)

This starts escaping when a ) and stops when it's current level is closed with (. So a nested () would not effect it.

1

Using re.sub('[()]', '', string) will replace any parenthesis in the string with an empty string.

To match the last set of balanced parenthesis, and if you can make use of the regex PyPi module, you can use a recursive pattern repeating the first sub group, and assert that to the right there are no more occurrences of either ( or )

(\((?:[^()\n]++|(?1))*\))(?=[^()\n]*$)

The pattern matches:

  • ( Capture group 1
    • \( Match (
    • (?:[^()\n]++|(?1))* Repeat 0+ times matching either any char except ( ) or a newline. If you do, recurse group 1 using (?1)
    • \) Match )
  • ) Close group 1
  • (?=[^()\n]*$) Positive lookahead, assert till the end of the string no ( or ) or newline

See a regex demo and a Python demo.

For example

import regex

strings = [
    "hell(h)o(world)",
    "hel(lo(wor)ld)",
    "hell(h)o(world)blahblahblah"
]

pattern = r"(\((?:[^()]++|(?1))*\))(?=[^()]*$)"

for s in strings:
    print(regex.sub(pattern, "", s))

Output

hell(h)o
hel
hell(h)oblahblahblah

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.