788498
788498

Reputation: 157

c# Regex replace <br /> or [br /] to "\n" between [pre=html]code[br /]code[/pre]

I have this code that replaces the BBCode to html, the problem arises when I want to replace the tags <br /> or [br /] that are within [pre=html] code [/pre].

Regex exp; string str;

 str = "more text [pre=html] code code code code [br /] code code code [br /] code code [/pre] more text";

 str = str.Replace("[br /]","<br />");

 exp = new Regex(@"\[b\](.+?)\[/b\]");
 exp.Replace str = (str,"<strong>$1</strong>");
 ......
 exp = new Regex (@ "\[pre\=([a-z\]]+)\]([\d\D\n^]+?)\[/pre\]");
 str = exp.Replace(str, "<pre class=\"$1\">" + "$2" + "</pre>");

As you would to change <br /> or [br /] with "\n" that are within [pre=html] code [/pre] or <pre class=html> code </pre>

Upvotes: 3

Views: 9420

Answers (1)

Sven
Sven

Reputation: 22683

It is in general almost impossible to express the constraint that something must only match if it is in between a matched pair of something else in a single regex.

It's easier to split this up into multiple operations, where you first find the [pre] blocks and then process their contents separately. It makes your code easier to write, understand and debug as well.

Here is an example of how to accomplish this:

static string ReplaceBreaks(string value)
{
    return Regex.Replace(value, @"(<br */>)|(\[br */\])", "\n");
}

static string ProcessCodeBlocks(string value)
{
    StringBuilder result = new StringBuilder();

    Match m = Regex.Match(value, @"\[pre=(?<lang>[a-z]+)\](?<code>.*?)\[/pre\]");
    int index = 0;
    while( m.Success )
    {
        if( m.Index > index )
            result.Append(value, index, m.Index - index);

        result.AppendFormat("<pre class=\"{0}\">", m.Groups["lang"].Value);
        result.Append(ReplaceBreaks(m.Groups["code"].Value));
        result.Append("</pre>");

        index = m.Index + m.Length;
        m = m.NextMatch();
    }

    if( index < value.Length )
        result.Append(value, index, value.Length - index);

    return result.ToString();
}

You'll have to modify it as needed to perform further processing, but I think this will get you started.

Upvotes: 5

Related Questions