0

This is my function.

class bbcode{
    var $bbcode_bb2html;
    function __construct($string){
            $this->bbcode_bb2html= $string;
    }
    function bbcode_parse_codes( ){
            $this->bbcode_bb2html = preg_replace("#\[code=(.*?)\](.*?)\[/code\]#si", "<pre data-snap-ignore=true class=language-\\1><code>\\2</code></pre>", $this->bbcode_bb2html);
            return $this->bbcode_bb2html;
    }
}
$content="[code=php]test message[/code]";
$bbcode = new bbcode($content);
echo $bbcode->bbcode_bb2html();   

True result

<pre data-snap-ignore=true class=language-php><code>test message</code></pre>

But nested message not work. Sample;

$content="[code=php]test message [code=php]...[/code] bla bla bla[/code]";
$bbcode = new bbcode($content);
echo $bbcode->bbcode_bb2html(); 

False Result

<pre data-snap-ignore=true class=language-php><code>test message [code=php]...</code></pre> bla bla bla[/code]

1
  • function bbcode_bb2html(){ if ( empty($this->bbcode_bb2html) ){ return ( false ); } $this->bbcode_parse_codes( ); return $this->bbcode_bb2html; } Commented Jan 30, 2022 at 20:21

1 Answer 1

1

You can use

\[code=([^]]*)]([^[]*(?:\[(?!/code]|code=)[^[]*)*)\[/code]

and replace until no match is found. See the regex demo. Details:

  • \[code= - a [code= string
  • ([^]]*) - Group 1: any zero or more chars other than ] char
  • ] - a ] char
  • ([^[]*(?:\[(?!/code]|code=)[^[]*)*) - Group 2: any zero or more chars other than a [ char, then zero or more occurrences of a [ char that is not immediately followed with /code] or code= and then zero or more chars other than a [ char
  • \[/code] - [/code] string.

In PHP code, it will look like

<?php

$text = '[code=php]test message [code=php]...[/code] bla bla bla[/code]';
$repl = '<pre data-snap-ignore=true class=language-$1><code>$2</code></pre>';
$count = 0;
do {
    $text = preg_replace('~\[code=([^]]*)]([^[]*(?:\[(?!/code]|code=)[^[]*)*)\[/code]~', $repl, $text, -1, $count);
} while ($count > 0);
echo $text;

Output:

<pre data-snap-ignore=true class=language-php><code>test message <pre data-snap-ignore=true class=language-php><code>...</code></pre> bla bla bla</code></pre>

To only get the surrounding tags you can use

(?s)\[code=([^]]*)]((?:(?!\[/?code\b).|(?R))*)\[/code]

See this regex demo. In PHP:

preg_replace('~\[code=([^]]*)]((?:(?!\[/?code\b).|(?R))*)\[/code]~s', $repl, $text)
Sign up to request clarification or add additional context in comments.

5 Comments

Your answer should be like this., <pre data-snap-ignore=true class=language-php><code>test message [code=php]...[/code] bla bla bla</code></pre>
@ulusanyazilim In the end you will still need to convert all these codes to html, won't you?
no, first and last tag only
@ulusanyazilim Then use regex recursion.
sample bbcode [code]asd[code]asd[/code]asd[/code] your code output <pre><code>asd<pre><code>asd</code></pre>asd</code></pre> i want to be like this <pre><code>asd[code]asd[/code]asd</code></pre>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.