Page 1 of 2

[SOLVED] BBCode!

Posted: Tue Feb 21, 2006 7:15 pm
by evilmonkey
Hello everyone. I'm writing a pretty simple forum that integrates with my user-driven website (hence the reason for not using something like phpBB). I need a function that will convert bbcode to normal HTML (simple bbcode, no lists or any of that). I only need bold, italics, underline, links, and images. Possibly font size. I have no idea where to start, I've never been good with regex. If someone can point me int he right direction, I'll really appreciate it.

Posted: Tue Feb 21, 2006 7:52 pm
by John Cartwright
consider the amount of articles/snipplets available on the net.. all I'm going to say is search google

key terms: PHP bbcode script

Posted: Tue Feb 21, 2006 9:10 pm
by evilmonkey
Yes, I actually knew about str_replace (I'm not that much of a newb :P ), it's the [img]and%20[url]%20that%20bother%20me.%20I'm%20guessing%20that%20I%20will%20have%20to%20use%20some%20regex%20to%20read%20what's%20between%20the%20[img]%20and[/img] tags. Ditto for [url].

Posted: Tue Feb 21, 2006 9:23 pm
by John Cartwright
You could always download phpBB and look at how they do it ;)

Posted: Tue Feb 21, 2006 9:24 pm
by josh
Yeah, there's tons of stuff already out there that's why jcart suggested you search google.. for example here's something I wrote

Code: Select all

<?php
class bbcode {

	var $text;
	
	function bbcode($text) {
		$this -> text =  $text;
	}
	
	function output() {
		echo($this->parse());
	}
	
	function parse() {
		$this-> text = $this -> formatting($this ->text);
		$this-> text = $this -> links($this ->text);
		return(nl2br($this->text));
	}
	
	function formatting($text) {
		$text = preg_replace('@\[b\](.*?)\[/b\]@ims', '<strong>\\1</strong>', $text);
		$text = preg_replace('@\[i\](.*?)\[/i\]@ims', '<i>\\1</i>', $text);
		$text = preg_replace('@\[u\](.*?)\[/u\]@ims', '<u>\\1</u>', $text);
		return($text);
	}

	function links($text) {
		$text = preg_replace('@\[url=(.*?)\](.*?)\[/url\]@ims', '<a href="\\1">\\2</a>', $text);
		return($text);
	}
}
?>

Posted: Tue Feb 21, 2006 9:30 pm
by John Cartwright
Might want to look into a stack based parser.. since


[quote] hi [quote] [/quote] [/quote] will fail in that, I believe.

Posted: Tue Feb 21, 2006 9:38 pm
by evilmonkey
jshpro, that's exactly what i was looking for. Thank you very much. Since I don't stand a chance in hell of learning regex, I'll just take it as it is. I understand what you're doing (and had something liket hat written), I just needed that regex code. Thanks very much, you really helped me out. :D

Posted: Tue Feb 21, 2006 9:53 pm
by josh
we don't have [quote] tags and this particular site didn't need nested tags anyway. This wasn't and end all solution just an example at how simple this is

Posted: Wed Feb 22, 2006 12:26 pm
by evilmonkey
I'm posting my bbcode function (takes care of the [quote] problem too) in hopes tha someone can learn from it. Thanks for your help everyone.

Code: Select all

function bbcode($text) {
	//bold
	$text = preg_replace('@\[b\](.*?)\[/b\]@ims', '<strong>\\1</strong>', $text);
    //italics
	$text = preg_replace('@\[i\](.*?)\[/i\]@ims', '<i>\\1</i>', $text);
    //underline
	$text = preg_replace('@\[u\](.*?)\[/u\]@ims', '<u>\\1</u>', $text);
    //links
	$text = preg_replace('@\[url=(.*?)\](.*?)\[/url\]@ims', '<a href="\\1">\\2</a>', $text);
    //images
	$text = preg_replace('@\[img\](.*?)\[/img\]@ims', '<img src="\\1">', $text);
    
    //quoting - with a source
    while (strpos($text, "[quote=")!== FALSE){
    	$text = preg_replace('@\[quote=(.*?)\](.*?)\[/quote\]@ims', '<table>
                <tr>
                  <td>&nbsp;</td>
                  <td>Quote:\\1</td>
                </tr>
                <tr>
                  <td>&nbsp;</td>
                  <td>\\2<br>
                   </td>
                </tr>
              </table>', $text);
    }
    //quoting - no source
    while (strpos($text, "[quote]")!==FALSE){
    	$text = preg_replace('@\[quote\](.*?)\[/quote\]@ims', '<table>
                <tr>
                  <td>&nbsp;</td>
                  <td>Quote:</td>
                </tr>
                <tr>
                  <td>&nbsp;</td>
                  <td>\\1<br>
                   </td>
                </tr>
              </table>', $text);, $text);
    }
	//line breaks
	$text = nl2br($text);
    return($text); 
}

Posted: Wed Feb 22, 2006 12:55 pm
by feyd
hopefully no one uses improper quotes or you could get infinite loops.

Posted: Wed Feb 22, 2006 2:32 pm
by evilmonkey
How would you? I made it to find exact matches of the string [quote] and [quote= (without the ending bracket). The only way I can see an infinite loop happenning is if some moron...pardon me...user decides to copy and paste the string [quote] many times. Even then, it's finite. If you see another issue, let me know so I can correct it. :)

Thanks.

Posted: Wed Feb 22, 2006 3:20 pm
by feyd
How is it finite? Users submit bad tags all the time. Btw, both these will create infinite loops:

Code: Select all

[quote]

Code: Select all

[quote=

Code: Select all

[quote=[/quote]

Posted: Wed Feb 22, 2006 3:25 pm
by josh
Yeah your while loop should be checking for the same text it is going to replace (regex), also this is a good place for a do..while loop

while loop for simple quote
check string
replace text
check string

do..while loop for simple quote
replace text
check string

Posted: Wed Feb 22, 2006 3:27 pm
by evilmonkey
fyed brought up a good point. I changed the condition of my loops:

Code: Select all

while (strpos($text, "[quote]")!==FALSE && strpos($text, "[/quote]"!==FALSE)){
//...
}
while (strpos($text, "[quote=")!== FALSE && strpos($text, "[/quote]"!==FALSE)){
//...
}
Thanks. :)

Posted: Wed Feb 22, 2006 3:31 pm
by evilmonkey
jshpro2 wrote:Yeah your while loop should be checking for the same text it is going to replace (regex), also this is a good place for a do..while loop

while loop for simple quote
check string
replace text
check string

do..while loop for simple quote
replace text
check string
I don't think do while is good for this case...why run the memory intensive regex function if there's no
tag at all?