Help - Search - Members - Calendar
Full Version: [PHP] BBCode Parser
Pixel2Life Forum > Member Tutorials and Requests > Forum Tutorial Archives > PHP Tutorials
HaloprO
Hi.
Setup a new php document and make a function called BBCode
CODE
<?php
function BBCode ($string) {

}
?>

Then we need to use regular expressions and arrays for the search and replace
CODE
<?php
function BBCode ($string) {
   $search = array(
       '\[b\](.*?)\[\/b\]\',
       '\[i\](.*?)\[\/i\]\',
       '\[u\](.*?)\[\/u\]\',
       '\[img\](.*?)\[\/img\]\',
       '\[url\=(.*?)\](.*?)\[\/url\]\',
       '\[code\](.*?)\[\/code\]\'
   );
   $replace = array(
       '<b>\\1</b>',
       '<i>\\1</i>',
       '<u>\\1</u>',
       '<img src="\\1">',
       '<a href="\\1">\\2</a>',
       '<code>\\1</code>'
   );
   return preg_replace($search, $replace, $string);
}
?>

That runs a search through a specified string, it tells it to look for b, i, u, img, url, and code.
It then turns it into html format.
Usuage of this function is
CODE
<?php
echo BBCode('Here is some [b]Bold![/b] and so on!');
?>

Enjoi.
Jaymz
Thanks for sharing smile.gif
Blitz
Thanks much! I could never figure how to do that.
Jaymz
There are some nice tutorials out there too to get the javascript buttons like IPB uses smile.gif I use the technique on a friend's personal site (which I did a quick CMS for) and she loves it. Makes it really easy to use bigwink.gif
HaloprO
Want me to put up a javascript tutorial on how to do it?
Blitz
Yeah, that'd be very useful if you could put up the javascript as well, that's what I've been looking for.

Oh, and just to let you know, it doesn't work. I get this error when trying to use it:

Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /*****/*****/*****/*****/www/blognetwork/ben/lib/code.php on line 10

Parse error: parse error, unexpected '[', expecting ')' in /*****/*****/*****/*****/www/blognetwork/ben/lib/code.php on line 10

I think it's because you're escaping the array for the bold [b]. \' will make it so that it'll display ' in your string, but since there isn't anything to end the string, it has problems.
softLearner
I see the erro i think as to start his expression for find in the tags he's using a backslash at the start and end of the expression convert them to forward slashes and you'll be fine, ie:
chnage
CODE
'\[b\](.*?)\[\/b\]\',
to
CODE
'/[b\](.*?)\[\/b\]/',


Alos add is to the end each expression so it can ignore line breaks and is case-insensitve, other wise if you want multiple lines to be bolded or underlined then you may find it wont actually do anything. so it replace with:
CODE
'/[b\](.*?)\[\/b\]/is',


Doing that for all the expressions and you'll be fine.

Also those that don't knw much about regular expression the square brackets ( [] ) actaully have a special meaning, so esacaping them by adding a backslash to them will make the PCRE engine to use them as prt of what your want it to look for.
HaloprO
Yeah it was supposed to be forward slashes not backslashes, And about the javascript, you mean the little (shades.gif etc buttons that insert it into the text field?
Blitz
Yeah. That'd be really great.
HaloprO
Ok, posting it now, be up in 5 minutes
Arutha
QUOTE(Jaymz @ Aug 13 2005, 07:02 PM)
There are some nice tutorials out there too to get the javascript buttons like IPB uses smile.gif I use the technique on a friend's personal site (which I did a quick CMS for) and she loves it. Makes it really easy to use bigwink.gif

care to share i love new ways of doing things makes life/coding more interesting
Jaymz
QUOTE(Arutha @ Aug 18 2005, 06:57 AM)
QUOTE(Jaymz @ Aug 13 2005, 07:02 PM)
There are some nice tutorials out there too to get the javascript buttons like IPB uses smile.gif I use the technique on a friend's personal site (which I did a quick CMS for) and she loves it. Makes it really easy to use bigwink.gif

care to share i love new ways of doing things makes life/coding more interesting

The bbcode is all admin-side and you can't tell from the site itself smile.gif But here it is smile.gif
Jynxis
hi... yeah i get an error with the code...

Heres wut i edited... well from wut i was told to do anyways.

CODE
function BBCode ($string) {
  $search = array(
      '/[b\](.*?)\[\/b\]/is',
      '/[i\](.*?)\[\/i\]/is',
      '/[u\](.*?)\[\/u\]/is',
      '/[img\](.*?)\[\/img\]/is',
      '/[url\=(.*?)\](.*?)\[\/url\]/is',
      '/[code\](.*?)\[\/code/]/is'
  );
  $replace = array(
      '<b>\\1</b>',
      '<i>\\1</i>',
      '<u>\\1</u>',
      '<img src="\\1">',
      '<a href="\\1">\\2</a>',
      '<code>\\1</code>'
  );
  return preg_replace($search, $replace, $string);
}



and heres teh Errors
CODE
Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 16 in /home/adminis/public_html/plague/viewtopic.php on line 133

Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 16 in /home/adminis/public_html/plague/viewtopic.php on line 133

Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 16 in /home/adminis/public_html/plague/viewtopic.php on line 133

Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 20 in /home/adminis/public_html/plague/viewtopic.php on line 133

Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 27 in /home/adminis/public_html/plague/viewtopic.php on line 133

Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 22 in /home/adminis/public_html/plague/viewtopic.php on line 133


this is a kewl bbcode function... and i really needed it.. .have been looking for awhile... it would be a shame to not have it work...lol...
eVoGre3n
Ya, im looking into this aswell
Blitz
PlaGuEX try this.

CODE
function BBCode ($string) {
 $search = array(
     '/\[b\](.*?)\[\/b\]/is',
     '/\[i\](.*?)\[\/i\]/is',
     '/\[u\](.*?)\[\/u\]/is',
     '/\[img\](.*?)\[\/img\]/is',
     '/\[url\=(.*?)\](.*?)\[\/url\]/is',
     '/\[code\](.*?)\[\/code/]/is'
 );
 $replace = array(
     '<b>\\1</b>',
     '<i>\\1</i>',
     '<u>\\1</u>',
     '<img src="\\1">',
     '<a href="\\1">\\2</a>',
     '<code>\\1</code>'
 );
 return preg_replace($search, $replace, $string);
}


He forgot to escape the [ characters. I don't know if that'll fix your problem, but it's worth a try.
rc69
Save space, think simple bigwink.gif
CODE
function BBCode ($string) {
$search = array(
    '#\[b\](.*?)\[/b\]#',
    '#\[i\](.*?)\[/i\]#',
    '#\[u\](.*?)\[/u\]#',
    '#\[img\](.*?)\[/img\]#',
    '#\[url=(.*?)\](.*?)\[/url\]#',
    '#\[code\](.*?)\[/code\]#'
);
$replace = array(
    '<b>\\1</b>',
    '<i>\\1</i>',
    '<u>\\1</u>',
    '<img src="\\1">',
    '<a href="\\1">\\2</a>',
    '<code>\\1</code>'
);
return preg_replace($search.'si', $replace, $string);
}


Simply took all the "is"'s out and put it in the preg_replace. Just makes thing's that much more simple.
Also used '#' around the expression to lessen how much you need to escape (and unescaped the "=" in the url code... no need).

p.s. "is" and "si" are the exact same thing, so don't think to correct me on that. smile.gif
Also, you may want to think about editing your original post so people can see the "correct" code and don't have to scroll down and sort through all the posts (or re-post the same error).
Developer
here is the right code
CODE
<?php
function BBCode ($string) {
$search = array(
    '#\[b\](.*?)\[/b\]#',
    '#\[i\](.*?)\[/i\]#',
    '#\[u\](.*?)\[/u\]#',
    '#\[img\](.*?)\[/img\]#',
    '#\[url=(.*?)\](.*?)\[/url\]#',
    '#\[code\](.*?)\[/code\]#'
);
$replace = array(
    '<b>\\1</b>',
    '<i>\\1</i>',
    '<u>\\1</u>',
    '<img src="\\1">',
    '<a href="\\1">\\2</a>',
    '<code>\\1</code>'
);
return preg_replace($search , $replace, $string);
}
?>
Jynxis
Acually an even better way to do it would be to have it like so.

CODE
function BBCode ($string) {
$search = array(
    '@\[(?i)b\](.*?)\[/(?i)b\]@si',
    '@\[(?i)i\](.*?)\[/(?i)i\]@si',
    '@\[(?i)u\](.*?)\[/(?i)u\]@si',
    '@\[(?i)img\](.*?)\[/(?i)img\]@si',
    '@\[(?i)url=(.*?)\](.*?)\[/(?i)url\]@si',
    '@\[(?i)code\](.*?)\[/(?i)code\]@si'
);
$replace = array(
    '<b>\\1</b>',
    '<i>\\1</i>',
    '<u>\\1</u>',
    '<img src="\\1">',
    '<a href="\\1">\\2</a>',
    '<code>\\1</code>'
);
return preg_replace($search , $replace, $string);
}


it will make the tags not so "case sensitive".

So that [iMg][/ImG] would still output the image.
rc69
You do know that if you have the i modifier at the end, you don't need the (?i)'s any where in the expression right?

Also, my last code is wrong... i forgot that adding .'si' would make it a string, rather then an array (which is wrong).
Jynxis
QUOTE(rc69 @ Dec 11 2005, 09:30 PM) *
You do know that if you have the i modifier at the end, you don't need the (?i)'s any where in the expression right?


I tried cust sticking the (?i) anywhere... and it didnt work.

all the (?i) does, is makes it not care about the "case".

I know it works cuz i tested it.
Indigo
QUOTE
Ok, posting it now, be up in 5 minutes

Could anyone post a link for the code they refer to? Really looking for it, but couldn't find it when I searched the forums sad.gif
rc69
Believe me, i've done my fair share of work with regular expressions... You don't need (?i) to make the expression case-insensative. If you don't want to take my word, take php.net's word.
http://php.net/manual/en/reference.pcre.pattern.syntax.php

And eh, indigo, have you tried searching the tutorial database...?
http://www.pixel2life.com/tutorials/JavaSc...&d=1&ss=smilies
Indigo
Thanks rc69, I feel quite stupid now. I thought it was supposed to be a tutorial posted in this forum, that's why I got confused.

But can't you guys just find something that works properly, and then post that code? Or do they all work just fine?
Hayden
QUOTE(rc69 @ Sep 5 2005, 09:41 PM) *
CODE
function BBCode ($string) {
$search = array(
    '#\[b\](.*?)\[/b\]#',
    '#\[i\](.*?)\[/i\]#',
    '#\[u\](.*?)\[/u\]#',
    '#\[img\](.*?)\[/img\]#',
    '#\[url=(.*?)\](.*?)\[/url\]#',
    '#\[code\](.*?)\[/code\]#'
);
$replace = array(
    '<b>\\1</b>',
    '<i>\\1</i>',
    '<u>\\1</u>',
    '<img src="\\1">',
    '<a href="\\1">\\2</a>',
    '<code>\\1</code>'
);
return preg_replace($search.'si', $replace, $string);
}


i copied this EXACTLY as is and it didn't work.

QUOTE
[Sat Mar 18 18:23:47 2006] [error] PHP Warning: preg_replace(): Unknown modifier ']' in /home/haydenk/public_html/test/bbcode.php on line 21
[Sat Mar 18 18:23:47 2006] [error] PHP Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 27 in /home/*/public_html/test/bbcode.php on line 21
[Sat Mar 18 18:23:47 2006] [error] PHP Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 20 in /home/*/public_html/test/bbcode.php on line 21
[Sat Mar 18 18:23:47 2006] [error] PHP Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 16 in /home/*/public_html/test/bbcode.php on line 21
[Sat Mar 18 18:23:47 2006] [error] PHP Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 16 in /home/*/public_html/test/bbcode.php on line 21
[Sat Mar 18 18:23:47 2006] [error] PHP Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 16 in /home/*/public_html/test/bbcode.php on line 21


got those in the error_log


QUOTE(PlaGuEX @ Dec 11 2005, 03:30 AM) *
Acually an even better way to do it would be to have it like so.

CODE
function BBCode ($string) {
$search = array(
    '@\[(?i)b\](.*?)\[/(?i)b\]@si',
    '@\[(?i)i\](.*?)\[/(?i)i\]@si',
    '@\[(?i)u\](.*?)\[/(?i)u\]@si',
    '@\[(?i)img\](.*?)\[/(?i)img\]@si',
    '@\[(?i)url=(.*?)\](.*?)\[/(?i)url\]@si',
    '@\[(?i)code\](.*?)\[/(?i)code\]@si'
);
$replace = array(
    '<b>\\1</b>',
    '<i>\\1</i>',
    '<u>\\1</u>',
    '<img src="\\1">',
    '<a href="\\1">\\2</a>',
    '<code>\\1</code>'
);
return preg_replace($search , $replace, $string);
}


replaced it with this and it works fine.

http://spaceghost.cc/test/bbcode.php
dEcade
Here is the way I do it and it works very nicley.

CODE
<?php
function bbcode ($string)
{
    // All the default bbcode arrays.
    $bbcode = array(
        //Text Apperence
        '#\[b\](.*?)\[/b\]#si' => '<b>\\1</b>',
        '#\[i\](.*?)\[/i\]#si' => '<i>\\1</i>',
        '#\[u\](.*?)\[/u\]#si' => '<u>\\1</u>',
        '#\[s\](.*?)\[/s\]#si' => '<strike>\\1</strike>',
        //Font Color
        '#\[color=(.*?)\](.*?)\[/color\]#si' => '<font color="\\1">\\2</font>',
        //Text Effects
        '#\[bl\](.*?)\[/bl\]#si' => '<blink>\\1</blink>',
        '#\[marquee\](.*?)\[/marquee\]#si' => '<marquee>\\1</marquee>',
        //Other
        '#\[code\](.*?)\[/ code]#si' => '<div class="bbcode_code_title">CODE:</div><div class="bbcode_code_code">\\1<div>',
        '#\[url=http://(.*?)\](.*?)\[/url]#si' => '<a href="\\1" target="_blank">\\2</a>',
        '#\[quote\](.*?)\[/quote\]#si' => '<div class="bbcode_quote_title">CODE:</div><div class="bbcode_quote_quote">\\1<div>',
        '#\[img\](.*?)\[/img\]#si' => '<img src="\\1">',
        '#\[email\](.*?)\[/email\]#si' => '<a href="mailto:\\1">\\1</a>'
    );
    $output = preg_replace(array_keys($bbcode), array_values($bbcode), $string);
    return $output;
}
?>


NOTCE: there is a space for the [/code] part so it looks like this [/ code] so that it code doesn't look funny. if you use it just take the space out.

It should work then to use the bbcode you would do this:

CODE
bbcode('stuff here [b]bold text[/b]');


So hope that helps you guys out.

dEcade
Hayden
Nice dEcade. victory.gif



Can anybody tell me how to add the smilie bbcode? tongue.gif
dEcade
Well I haven't try this but basically I think you would do something like this on the page that your forum thing submits to.

CODE
<?php
function set_smiley($string)
{
$new_string = str_replace(':)', 'SMILEY HTML HERE');
return $new_string;
}
?>


Then you would run the script when you posted it so something like this:

Note: This is the whole script put together.

CODE
<?php
function set_smiley($string)
{
$new_string = str_replace(':)', 'SMILEY HTML HERE');
return $new_string;
}

if(isset($_POST['submit'])
{
$post = set_smiley($_POST['post']); // Notice your text area must be named post.
echo $post;
}
else
{
echo 'Your Forum Goes Here';
}
?>


If you are trying this script out make sure that the submit button is named submit other wise it won't submit. If it doesn't replace the : ) with the SMILEY HTML HERE or your html then try a preg_replace or something. This script is not tested so it may not work.

dEcade
Hayden
hmmm, okay.


i was thinking there'd be a way to integrated into the bbcode function. blink.gif
Boom
great tutorial, thanks.
rus321
just make 2 diffrent functions:

bbcode(set_smiley('text'));
Av-
Now how would you turn plain http://mysite.com text into a link, just like on this forum, without messing up the url bbcode
Mr. Jay
QUOTE(PlaGuEX @ Dec 10 2005, 09:30 PM) *
Acually an even better way to do it would be to have it like so.

CODE
function BBCode ($string) {
$search = array(
    '@\[(?i)b\](.*?)\[/(?i)b\]@si',
    '@\[(?i)i\](.*?)\[/(?i)i\]@si',
    '@\[(?i)u\](.*?)\[/(?i)u\]@si',
    '@\[(?i)img\](.*?)\[/(?i)img\]@si',
    '@\[(?i)url=(.*?)\](.*?)\[/(?i)url\]@si',
    '@\[(?i)code\](.*?)\[/(?i)code\]@si'
);
$replace = array(
    '<b>\\1</b>',
    '<i>\\1</i>',
    '<u>\\1</u>',
    '<img src="\\1">',
    '<a href="\\1">\\2</a>',
    '<code>\\1</code>'
);
return preg_replace($search , $replace, $string);
}


it will make the tags not so "case sensitive".

So that [iMg][/ImG] would still output the image.


The URL BBCode doesnt work for me sad.gif

I tried this, but it stays the same sad.gif
CODE
[url=http://www.google.com/]GOOGLE[/url]



Edit: I replaced the url BBCODE with this 1 and it works smile.gif
CODE
'@\[url\s*=\s*(.*?)\s*\](.*?)\[\/url\]@si',
SecondV
CODE
<?php

function parse_bbcode($text, $xhtml = true)
{
    $tags = array(
        '#\[b\](.*?)\[/b\]#si' => ($xhtml ? '<strong>\\1</strong>' : '<b>\\1</b>'),
        '#\[i\](.*?)\[/i\]#si' => ($xhtml ? '<em>\\1</em>' : '<i>\\1</i>'),
        '#\[u\](.*?)\[/u\]#si' => ($xhtml ? '<span style="text-decoration: underline;">\\1</span>' : '<u>\\1</u>'),
        '#\[s\](.*?)\[/s\]#si' => ($xhtml ? '<strike>\\1</strike>' : '<s>\\1</s>'),
        '#\[color=(.*?)\](.*?)\[/color\]#si' => ($xhtml ? '<span style="color: \\1;">\\2</span>' : '<font color="\\1">\\2</font>'),
        '#\[img\](.*?)\[/img\]#si' => ($xhtml ? '<img src="\\1" border="0" alt="" />' : '<img src="\\1" border="0" alt="">'),
        '#\[url=(.*?)\](.*?)\[/url\]#si' => '<a href="\\1" title="\\2">\\2</a>',
        '#\[email\](.*?)\[/email\]#si' => '<a href="mailto:\\1" title="Email \\1">\\1</a>',
        '#\[code\](.*?)\[/code\]#si' => '<code>\\1</code>',
        '#\[align=(.*?)\](.*?)\[/align\]#si' => ($xhtml ? '<div style="text-align: \\1;">\\2</div>' : '<div align="\\1">\\2</div>'),
        '#\[br\]#si' => ($xhtml ? '<br style="clear: both;" />' : '<br>'),
    );

    foreach ($tags AS $search => $replace)
    {
        $text = preg_replace($search, $replace, $text);
    }
    return $text;
}

function parse_smilies($text)
{
    $smilies = array(
        ':)' => '<img src="images/smilies/smile.gif" border="0" alt="Smile" title="Smile" />',
        ':(' => '<img src="images/smilies/sad.gif" border="0" alt="Sad" title="Sad" />',
        ':D' => '<img src="images/smilies/biggrin.gif" border="0" alt="Big Grin" title="Big Grin" />',
        ':S' => '<img src="images/smilies/confused.gif" border="0" alt="Confused" title="Confused" />'
        // etc
    );

    foreach ($smilies AS $search => $replace)
    {
        $text = str_replace($search, $replace, $text);
    }
    return $text;
}

?>


CODE
<?php

echo parse_bbcode('[align=center][b][color=red]Testing[/color][/b][br]');

?>


HTML
<div style="text-align: center;"><strong><span style="color: red;">Testing</span></strong><br style="clear: both;" /></div>


smile.gif
Nightscream
ok just read this, looks great, testing it later
but a question why do you have to do
@\[(?i)b\](.*?)\[/(?i)b\]@si

why use those ugly marks?

and why \\1? where does the \\ stand for and the 1?
<b>\\1</b>
rc69
http://www.pixel2life.com/forums/index.php...st&p=114029

Read the above post, and if you want, the next few posts after that. Then to understand the backslashes, first you have to understand Regex. You can read php.net's manual on Patter Syntax for info about that. But i find the whole thing to be confusing when taken in a large dose. So, to answer your question, scroll down to the section on "Back References" and understand that inside of a string, in order to get a single backslash, you need two.
Nightscream
ty i'll try that! smile.gif
Balor
Shouldn't you first strip all html tags?

I did also a bbcode script some time ago, here is what I did, it's almost the same imho:

CODE
function bbcode($text) {
        
        $text = strip_tags($text, '<br>');
    
        $suche = array('/\[b\](.+?)\[\/b\]/i',
                       '/\[i\](.+?)\[\/i\]/i',
                       '/\[u\](.+?)\[\/u\]/i',
                       '/\[url=(.+?)\](.+?)\[\/url\]/i',
                       '/\[file(.+?)\|(.+?)\]/i',
                       '/\:\)/i',
                       '/\;\)/i',
                       '/\:D/i',
                       '/\:p/i',
                       '/\:\'\(/i',
                       '/\[key\](.+?)\[\/key\]/ie',
                       '/\[quote\](.+?)\[\/quote\]/is',
                       '/\[color=(.+?)\](.+?)\[\/color\]/i');
        
        $code = array('<strong>$1</strong>',
                      '<i>$1</i>',
                      '<u>$1</u>',
                      '<img src="images/bigger.gif" alt="new_window" width="12px" height="12px" /><a href="$1" class="link" target="_blank">$2</a>',
                      '<a href="view.php?id=$1" class="link">$2</a>',
                      '<img src="images/smilies/smile.gif" alt=":)" />',
                      '<img src="images/smilies/wink.gif" alt=";)" />',
                      '<img src="images/smilies/laugh.gif" alt=":D" />',
                      '<img src="images/smilies/tounge.gif" alt=":p" />',
                      '<img src="images/smilies/worried.gif" alt=":\'(" />',
                      '$test->create_serial("$1")',
                      '<br /><div class="quote">$1</div><br />',
                      '<span style="color: $1;">$2</span>');
        
        $text = stripslashes($text);
        $text = preg_replace($suche, $code, $text);
        $text = nl2br($text);
        
        return $text;
    }
killeredge
QUOTE(Avalanche @ Mar 26 2006, 08:04 AM) *
Now how would you turn plain http://mysite.com text into a link, just like on this forum, without messing up the url bbcode


i have created an OOP BBCode Parser that also auto-parses links with and without the [url] tag.

inside the main class i have
CODE
// Automatically parse urls
           $code = preg_replace_callback("#(^|\s|>)((http|https|news|ftp)://\w+[^\s\[\]\<]+)#i", array( &$this, 'autourl' ), $code);


and to complete this, i have a function called autourl, that formats the url into forum-friendly and user-friendly urls. winner_first_h4h.gif shades.gif victory.gif
Ultimate`
Wow, cheers for this! wasn't thinking it would be this easy hahaha, did have an idea on what to do though =]
Mr.Shawn
Nice one here.
derek.sullivan
make life easy lol

use the array function and str_replace

CODE
<?php

$bb_Code = array(
'[code]' => '<code>',
'[/ code ]' => '</ code>'
); // so on so forth with the bbcode

foreach ($bb_Code as $value => $replace) {

$text = str_replace($value, $replace, $text);

}

echo $text;

?>


simple stuff.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2009 Invision Power Services, Inc.