I'm trying to remove the characters between the parentheses and brackets based on the length of characters inside the parentheses and brackets.
Using this:
def remove_text_inside_brackets(text, brackets="()[]"):
count = [0] * (len(brackets) // 2) # count open/close brackets
saved_chars = []
for character in text:
for i, b in enumerate(brackets):
if character == b: # found bracket
kind, is_close = divmod(i, 2)
count[kind] += (-1)**is_close # `+1`: open, `-1`: close
if count[kind] < 0: # unbalanced bracket
count[kind] = 0 # keep it
else: # found bracket to remove
break
else: # character is not a [balanced] bracket
if not any(count): # outside brackets
saved_chars.append(character)
return ''.join(saved_chars)
I'm able to remove the characters between the parentheses and brackets, but I cannot figure out how to remove the characters based on the length of characters inside.
I wanted to remove characters between the parentheses and brackets if the length <=4 with parentheses and brackets if they are >4 remove only parentheses and brackets.
Sample Text:
text = "This is a sentence. (RMVE) (Once a day) [twice a day] [RMV]"
Output:
print(remove_text_inside_brackets(text))
This is a sentence.
Desired Output:
This is a sentence. Once a day twice a day
You can use a simple regex with re.sub and a function as replacement to check the length of the match:
import re
out = re.sub('\(.*?\)|\[.*?\]',
lambda m: '' if len(m.group())<=(4+2) else m.group()[1:-1],
text)
Output:
'This is a sentence. Once a day twice a day '
This give you the logic for more complex checks, in which case you might want to define a named function rather than a lambda
How about splitting on [ and look for ] and measure length (since each split with ] will be necessarily longer than normal split, 4 becomes 5):
def remove_text_inside_brackets(string):
my_str = string.replace('(','[').replace(')',']')
out = []
for s in my_str.split('['):
if ']' in s and len(s) > 5:
s1 = s.rstrip().rstrip(']') + ' '
elif ']' in s and len(s) <= 5:
s1 = ['']
else:
s1 = s
out.extend(s1)
return ''.join(out).strip()
remove_text_inside_brackets(text)
Output:
'This is a sentence. RMVE Once a day twice a day'
Someone will hopefully improve on this, but as an alternative, this nested regular expression can work:
re.sub(r'\[([^)]{5,})\]', '\g<1>',
re.sub(r'\(([^)]{5,})\)', '\g<1>',
re.sub(r'\[[^\]]{,4}\]', '',
re.sub(r'\([^)]{,4}\)', '', text))))
Note that extra spaces, after the period and at the end of the line.
The output of this is slightly different than your given expected output:
'This is a sentence. Once a day twice a day '
It completely removes text and its surrounding brackets when the length is 4 or shorter, while it replaces the match with just the inner text where the length if 5 or longer.
Note that nested brackets, e.g., ((some text) more text) or [(four)] may fail.