How to remove brackets around substrings of a specific length?

Viewed 62

I'm able to remove brackets entirely from a string using the following Python function:

def bracket_remove(smi):
    remove_chars = ['[', ']']
    return ''.join((filter(lambda i: i not in remove_chars, smi)))

However, there are some cases where I want to keep bracketed sections. Specifically, I only want to remove brackets if the brackets enclose a single character. For example, [N][C@H]([C])[C](=O)[O] would become N[C@H](C)C(=O)O. Regular expressions seem like the way to go here, but I haven't been able to find much that's relevant for this problem. The closest regular expression solution I could find was:

import re
test_str = "[N][C@H]([C])[C](=O)[O]"
m = re.search(r"\[(\w+)\]", test_str)
print(m.group(1))

This returns only the first instance of bracketed characters (N), while I had thought it would identify cases where multiple characters were present between brackets. How would I modify this expression to find only the substrings with multiple characters (alphanumeric or otherwise) between brackets?

1 Answers

You can use

re.sub(r'\[(\w)]', r'\1', text)
# Or any char other than brackets
re.sub(r'\[([^][])]', r'\1', text)

See regex # demo and regex #2 demo.

Details

  • \[ - matches a [ char
  • (\w) - captures any letter/digit/connector punctuation into Group 1
  • ([^][]) - captures any char other than [ and ]
  • ] - matche a ] char.

The \1 in the replacement pattern replaces each match with the contents of Group 1 value.

See the Python demo:

import re
text = '[N][C@H]([C])[C](=O)[O]'
print(re.sub(r'\[(\w)]', r'\1', text))
# => N[C@H](C)C(=O)O
# Or any char other than brackets
print(re.sub(r'\[([^][])]', r'\1', text))
# => N[C@H](C)C(=O)O
Related