To me, this situation seems to be straight out of Match (or replace) a pattern except in situations s1, s2, s3 etc. Please visit that link for full discussion of the solution.
I will give you answers for both PHP and Python (since the example mentioned django).
PHP
(?s)\[code\].*?\[/code\](*SKIP)(*F)|\n
The left side of the alternation matches complete [code]...[/code] tags, then deliberately fails, and skips the part of the string that was just matched. The right side matches newlines, and we know they are the right newlines because they were not matched by the expression on the left.
This PHP program shows how to use the regex (see the results at the bottom of the online demo):
<?php
$regex = '~(?s)\[code\].*?\[/code\](*SKIP)(*F)|\n~';
$subject = "These concepts are represented by simple Python classes.
Edit the polls/models.py file so it looks like this:
[code]
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
[/code]";
$replaced = preg_replace($regex,"<br />",$subject);
echo $replaced."<br />\n";
?>
Python
For Python, here's our simple regex:
(?s)\[code\].*?\[/code\]|(\n)
The left side of the alternation matches complete [code]...[/code]
tags. We will ignore these matches. The right side matches and captures newlines to Group 1, and we know they are the right newlines because they were not matched by the expression on the left.
This Python program shows how to use the regex (see the results at the bottom of the online demo):
import re
subject = """These concepts are represented by simple Python classes.
Edit the polls/models.py file so it looks like this:
[code]
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
[/code]"""
regex = re.compile(r'(?s)\[code\].*?\[/code\]|(\n)')
def myreplacement(m):
if m.group(1):
return "<br />"
else:
return m.group(0)
replaced = regex.sub(myreplacement, subject)
print(replaced)