regex
text processing
string manipulation
delimiters
programming

Remove text in-between delimiters in a string using a regex?

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Yes, regular expressions can remove text between delimiters, but the right pattern depends on whether you want the delimiters removed too, whether matches can span multiple lines, and whether nested delimiters are possible. Regex works well for simple non-nested cases; for nested structures, a real parser is often the safer choice.

The Basic Non-Greedy Pattern

Suppose you want to remove text inside square brackets and remove the brackets themselves as well.

python
1import re
2
3text = "Hello [remove this] world"
4result = re.sub(r"\[.*?\]", "", text)
5print(result)

The important part is .*?, which is a non-greedy match. Without the question mark, the regex may consume too much.

Why Greedy Matching Often Breaks

Given this input:

text
A [one] B [two] C

A greedy pattern such as \[.*\] matches from the first [ to the last ], which removes more than intended. The non-greedy form \[.*?\] matches the shortest valid span instead.

That is one of the most common regex mistakes in delimiter-based text removal.

Keep or Remove the Delimiters Deliberately

If you want to keep the delimiters and remove only the interior text, use capturing groups.

python
1import re
2
3text = "Hello [remove this] world"
4result = re.sub(r"(\[).*?(\])", r"\1\2", text)
5print(result)

Now the output keeps the brackets but removes the content between them.

The exact replacement string depends on whether you want empty delimiters, a placeholder, or complete removal.

Multiline Content Needs Special Handling

The dot does not match newline characters by default. If the delimited content can span lines, add the re.DOTALL flag.

python
1import re
2
3text = "Start [line1\nline2] End"
4result = re.sub(r"\[.*?\]", "", text, flags=re.DOTALL)
5print(result)

Without re.DOTALL, the regex stops at the line boundary and fails to match the full block.

Custom Delimiters Work the Same Way

The delimiters do not have to be brackets. For custom strings such as << and >>, escape only what the regex engine treats as special.

python
1import re
2
3text = "alpha <<secret>> beta <<hidden>> gamma"
4result = re.sub(r"<<.*?>>", "", text)
5print(result)

The same non-greedy idea applies.

Regex Is Not Great for Nested Structures

Regex is fine for simple flat delimiters. It is not a good general solution for nested constructs such as:

text
[a [nested] value]

At that point, a regex-based approach becomes fragile because balanced nested structures are not what ordinary regular expressions handle well.

If nesting matters, write a parser or use a stack-based scan instead.

A Safer Parser for One Delimiter Pair

For nested brackets, a small parser is often clearer than fighting the regex engine.

python
1def remove_bracketed(text: str) -> str:
2    result = []
3    depth = 0
4
5    for ch in text:
6        if ch == '[':
7            depth += 1
8            continue
9        if ch == ']':
10            depth = max(depth - 1, 0)
11            continue
12        if depth == 0:
13            result.append(ch)
14
15    return ''.join(result)
16
17print(remove_bracketed("A [one [two]] B"))

This is often easier to trust when the input format is more complex than a flat regex pattern can describe.

Common Pitfalls

The most common mistake is using a greedy pattern and removing far more text than intended.

Another common issue is forgetting re.DOTALL when the delimited text spans multiple lines. Developers also often reach for regex even when the input can contain nested delimiters, where a parser is the safer tool.

Summary

  • Use a non-greedy regex such as \[.*?\] for simple flat delimiter removal.
  • Decide explicitly whether the delimiters themselves should stay or disappear.
  • Add re.DOTALL when matches may span multiple lines.
  • Regex is appropriate for simple non-nested structures.
  • Use a parser or stack-based scan when delimiters can be nested.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.