5 Best Ways to Reverse a Substring Enclosed Within Brackets in Python

πŸ’‘ Problem Formulation: We often face the challenge of manipulating strings in programming. In this article, we explore the specific problem of reversing substrings within brackets. Given an input string like "Hello [World]!", our goal is to reverse the part enclosed in brackets to achieve an output like "Hello [dlroW]!". Let’s examine various Python methods to tackle this task efficiently.

Method 1: Using Stack

This method uses a stack to track characters and brackets. When an opening bracket is encountered, the subsequent characters are pushed onto the stack until a closing bracket is found. Then the characters are popped (reversed order) off the stack.

Here’s an example:

def reverse_substring(s):
    stack = []
    result = ""
    for char in s:
        if char == '[':
            stack.append(result)
            result = ""
        elif char == ']':
            result = stack.pop() + result[::-1]
        else:
            result += char
    return result

print(reverse_substring("Hello [World]!"))

Output: Hello [dlroW]!

The function reverse_substring() navigates through the input string character by character, utilizing a stack to store characters that are within brackets. After detecting a closing bracket, it reverses the substring and resumes normal string concatenation until the next bracket is encountered.

Method 2: Recursive Approach

By employing a recursive function, we can reverse the substring within brackets from innermost to outermost by identifying pairs of brackets and reversing the text within.

Here’s an example:

def reverse_substring(s):
    def helper(subs):
        if '[' not in subs:
            return subs[::-1]
        open_bracket = subs.rfind('[')
        close_bracket = subs.find(']', open_bracket)
        return helper(subs[:open_bracket] + subs[open_bracket+1:close_bracket][::-1] + subs[close_bracket+1:])
    return helper(s)

print(reverse_substring("Hello [Wo[rld]]!"))

Output: Hello [dl[roW]]!

This recursive method reverse_substring() finds the last opening bracket and the first closing bracket after that to isolate the innermost substring. It reverses it and continues until there are no more brackets to process.

Method 3: Iterative Through Indices

This technique involves finding bracket indices and reversing substrings iteratively without using stack data structures or recursion.

Here’s an example:

def reverse_substring(s):
    while '[' in s:
        start = s.rfind('[')
        end = s.find(']', start)
        s = s[:start] + s[start+1:end][::-1] + s[end+1:]
    return s

print(reverse_substring("Hello [World]!"))

Output: Hello [dlroW]!

By repeatedly searching for the last opening bracket and the first closing bracket that follows, the method reverse_substring() consistently reverses the innermost substrings until no brackets remain, concatenating non-bracketed parts as needed.

Method 4: Using Regular Expressions

Regular expressions can be used to match all bracketed substrings and reverse them using a function that applies to each match found.

Here’s an example:

import re

def reverse_substring(s):
    return re.sub(r'\[([^\[\]]*)\]', lambda match: '[' + match.group(1)[::-1] + ']', s)

print(reverse_substring("Hello [World]!"))

Output: Hello [dlroW]!

In this method, the reverse_substring() function uses the sub() method from the re module to search for patterns that represent strings within brackets, replace them with their reversed form using a lambda expression.

Bonus One-Liner Method 5: Using The walrus Operator

A one-liner method can be devised using Python 3.8’s walrus operator, which allows assignment and return of values within an expression.

Here’s an example:

import re

print((lambda s: re.sub(r'\[([^\[\]]*)\]', lambda x: f'[{(y:=x.group(1))[::-1]}]', s))("Hello [World]!"))

Output: Hello [dlroW]!

The above code defines a lambda function that leverages a nested lambda with the walrus operator to reverse substrings inline. It’s compact and exploits Python 3.8’s assignment expressions to perform the substitution and reversal in a single pass.

Summary/Discussion

  • Method 1: Stack. It breaks down the string into manageable parts, processing each bracketed portion one at a time. It’s easy to follow but might not be the most efficient for deeply nested brackets.
  • Method 2: Recursive Approach. This approach elegantly handles nested brackets but may become problematic with very long input strings due to the limits of recursion depth.
  • Method 3: Iterative Through Indices. It’s straightforward and does not rely on complex data structures. However, repeated calls to string find methods can be inefficient.
  • Method 4: Regular Expressions. Regex is powerful and concise for pattern matching but can become less readable with more complex scenarios. It’s a quick solution for simpler, non-nested brackets.
  • Method 5: walrus Operator. This is the most concise and is ideal for fans of code golf. However, the walrus operator can obfuscate the logic, and debugging might be more difficult.