Jump to content

[SOLVED] Regex BBcode Help


Xyphon

Recommended Posts

<?PHP
    //Functions
    function parseBBCode($data) {
        $BBCODE = array();
        $BBCODE_REPLACEMENT = array();
        $BBCODE[]             = '/\[i\](.*?)\[\/i\]/';
        $BBCODE_REPLACEMENT[] = '<em>$1</em>';
        $BBCODE[]             = '/\[u\](.*?)\[\/u\]/';
        $BBCODE_REPLACEMENT[] = '<span style="text-decoration: underline;">$1</span>';
        $BBCODE[]             = '/\[em\](.*?)\[\/em\]/';
        $BBCODE_REPLACEMENT[] = '<em>$1</em>';
        $BBCODE[]             = '/\[s\](.*?)\[\/s\]/';
        $BBCODE_REPLACEMENT[] = '<s>$1</s>';
        $BBCODE[]             = '/\[strong\](.*?)\[\/strong\]/';
        $BBCODE_REPLACEMENT[] = '<strong>$1</strong>';
        $BBCODE[]             = '/\[b\](.*?)\[\/b\]/';
        $BBCODE_REPLACEMENT[] = '<strong>$1</strong>';
        $BBCODE[]             = '/\[img\](.*?)\[\/img\]/';
        $BBCODE_REPLACEMENT[] = '<img src="$1" alt="User Posted Image" />';
        $BBCODE[]             = '/\[img=(.*?)\](.*?)\[\/img\]/';
        $BBCODE_REPLACEMENT[] = '<img src="$1" alt="User Posted Image" title="$2" />';
        //$BBCODE[]             = '/(http:\/\/[a-zA-Z0-9\?#\/\._\-\+=\|&;]+)/';
        //$BBCODE_REPLACEMENT[] = '[url=$1]Link[/url]';
        $BBCODE[]             = '/\[url=(.*?)\](.*?)\[\/url\]/';
        $BBCODE_REPLACEMENT[] = '<a href="$1" target="_blank">$2</a>';
        $BBCODE[]             = '/\[comment\](.*?)\[\/comment\]/';
        $BBCODE_REPLACEMENT[] = '<!-- $1 -->';
        $BBCODE[]             = '/\[heading=(.*?)\](.*?)\[\/heading\]/';
        $BBCODE_REPLACEMENT[] = '<h3 id="heading:$1"><a href="#heading:$1">$2</a></h3>';
        $BBCODE[]             = '/\[spoiler\](.*?)\[\/spoiler\]/';
        $BBCODE_REPLACEMENT[] = '{Spoiler:<span class="spoiler">$1</span>}';
        $BBCODE[]             = '/\[colou?r=(.*?)\](.*?)\[\/colou?r\]/';
        $BBCODE_REPLACEMENT[] = '<span style="color: $1;">$2</span>';
        $BBCODE[]             = '/\[quote\](.*?)\[\/quote\]/';
        $BBCODE_REPLACEMENT[] = '<div class="quote">Quote:<br /><br />$1<br /></div>';
        $BBCODE[]             = '/\[quote=(.*?)\](.*?)\[\/quote\]/';
        $BBCODE_REPLACEMENT[] = '<div class="quote"><em>$1</em> said:<br /><br />$2<br /></div>';
        $BBCODE[]             = '/\[user\](.*?)\[\/user\]/';
        $BBCODE_REPLACEMENT[] = '<a href="viewprofile.php?id=$1" class="profileLink">$1</a>';
        $BBCODE[]             = '/\[collapse\](.*?)\[\/collapse\]/';
        $BBCODE_REPLACEMENT[] = '<div class="collapse">$1</div>';
        
        $SMILEYS = array();
        $SMILEYS_REPLACE = array();
        $SMILEYS[]         = '';
        $SMILEYS_REPLACE[] = '<img src="Images/smileys/smile.png"  alt="" />';
        $SMILEYS[]         = '';
        $SMILEYS_REPLACE[] = '<img src="Images/smileys/sad.png"  alt="" />';
        $SMILEYS[]         = ':@';
        $SMILEYS_REPLACE[] = '<img src="Images/smileys/angry.png"  alt=":@" />';
        $SMILEYS[]         = ':|';
        $SMILEYS_REPLACE[] = '<img src="Images/smileys/straightFace.png"  alt=":|" />';
        $SMILEYS[]         = '';
        $SMILEYS_REPLACE[] = '<img src="Images/smileys/shocked.png"  alt="" />';
        $SMILEYS[]         = '';
        $SMILEYS_REPLACE[] = '<img src="Images/smileys/wink.png"  alt="" />';
        $SMILEYS[]         = '';
        $SMILEYS_REPLACE[] = '<img src="Images/smileys/grin.png"  alt="" />';
        $SMILEYS[]         = '';
        $SMILEYS_REPLACE[] = '<img src="Images/smileys/tongue.png"  alt="" />';
        
        $CENSORS = array();
        $CENSORS_REPLACE = array();
        $CENSORS[] = 'fuck';
        $CENSORS_REPLACE[] = 'f***';
        $CENSORS[] = 'nigger';
        $CENSORS_REPLACE[] = 'n***er';
        $CENSORS[] = 'cock';
        $CENSORS_REPLACE[] = 'c**k';
        //Start with htmlentities
        $data = htmlentities($data);
//New lines, double spaces
        
$data = str_replace(array("\n",'  '),array('<br />','  '),$data);
        //Replace tags
        $data = preg_replace($BBCODE,$BBCODE_REPLACEMENT,$data);
        //Replace smileys
        $data = str_replace($SMILEYS,$SMILEYS_REPLACE,$data);
        //Replace curses
        $data = str_ireplace($CENSORS,$CENSORS_REPLACE,$data);
        return $data;
    }
?>

 

That's my script. Now the problem is, it won't double tag.

 

Like, if It type

 

[b][b][/b][/b]

 

it'll output it as

[b][/b]

 

At first this doesnt seem like much but if I do this

 

[quote][quote]Hi[/quote][/quote]

 

Inside a div it'll say:

 

[quote]Hi

And outside it it'll say:

[/quote]

 

Any way to fix this? Thanks.

Link to comment
https://forums.phpfreaks.com/topic/166667-solved-regex-bbcode-help/
Share on other sites

At best, it is difficult to handle nested tagging with regex.  But anyways, your solution is going to involve more than a simple preg_replace.  You will first need to go through and preg_match_all or strripos to find the last occurrence of the opening tag, then replace starting on that position.  Wash rinse and repeat for every other opening tag, going backwards to forwards (working your way inside-out). 

I know this is kind of stupid, but I thought of an idea and I just copy and pasted the

 

        $BBCODE[]             = '/\[i\](.*?)\[\/i\]/';
        $BBCODE_REPLACEMENT[] = '<em>$1</em>';
        $BBCODE[]             = '/\[u\](.*?)\[\/u\]/';
        $BBCODE_REPLACEMENT[] = '<span style="text-decoration: underline;">$1</span>';
        $BBCODE[]             = '/\[em\](.*?)\[\/em\]/';
        $BBCODE_REPLACEMENT[] = '<em>$1</em>';
        $BBCODE[]             = '/\[s\](.*?)\[\/s\]/';
        $BBCODE_REPLACEMENT[] = '<s>$1</s>';
        $BBCODE[]             = '/\[strong\](.*?)\[\/strong\]/';
        $BBCODE_REPLACEMENT[] = '<strong>$1</strong>';
        $BBCODE[]             = '/\[b\](.*?)\[\/b\]/';
        $BBCODE_REPLACEMENT[] = '<strong>$1</strong>';
        $BBCODE[]             = '/\[img\](.*?)\[\/img\]/';
        $BBCODE_REPLACEMENT[] = '<img src="$1" alt="User Posted Image" />';
        $BBCODE[]             = '/\[img=(.*?)\](.*?)\[\/img\]/';
        $BBCODE_REPLACEMENT[] = '<img src="$1" alt="User Posted Image" title="$2" />';
        //$BBCODE[]             = '/(http:\/\/[a-zA-Z0-9\?#\/\._\-\+=\|&;]+)/';
        //$BBCODE_REPLACEMENT[] = '[url=$1]Link[/url]';
        $BBCODE[]             = '/\[url=(.*?)\](.*?)\[\/url\]/';
        $BBCODE_REPLACEMENT[] = '<a href="$1" target="_blank">$2</a>';
        $BBCODE[]             = '/\[comment\](.*?)\[\/comment\]/';
        $BBCODE_REPLACEMENT[] = '<!-- $1 -->';
        $BBCODE[]             = '/\[heading=(.*?)\](.*?)\[\/heading\]/';
        $BBCODE_REPLACEMENT[] = '<h3 id="heading:$1"><a href="#heading:$1">$2</a></h3>';
        $BBCODE[]             = '/\[spoiler\](.*?)\[\/spoiler\]/';
        $BBCODE_REPLACEMENT[] = '{Spoiler:<span class="spoiler">$1</span>}';
        $BBCODE[]             = '/\[colou?r=(.*?)\](.*?)\[\/colou?r\]/';
        $BBCODE_REPLACEMENT[] = '<span style="color: $1;">$2</span>';
        $BBCODE[]             = '/\[quote\](.*?)\[\/quote\]/';
        $BBCODE_REPLACEMENT[] = '<div id="quote"><center>Quote:<br /><br />$1<br /></center></div>';
        $BBCODE[]             = '/\[quote=(.*?)\](.*?)\[\/quote\]/';
        $BBCODE_REPLACEMENT[] = '<div id="quote"><center><em>$1</em> said:<br /><br />$2<br /></center></div>';
        $BBCODE[]             = '/\[user\](.*?)\[\/user\]/';
        $BBCODE_REPLACEMENT[] = '<a href="viewprofile.php?id=$1" class="profileLink">$1</a>';
        $BBCODE[]             = '/\[collapse\](.*?)\[\/collapse\]/';
        $BBCODE_REPLACEMENT[] = '<div class="collapse">$1</div>';

about 30 times, which will make it read it 30 times. xD

 

EDIT: And I realizied after 3 quotes, it wont read the comment ID, will have to do one of your guys ideas.

The simple solution to nested BBCode tags is to handle the opening and closing tags individually; see this post.

 

brilliant! Haha why did I never think of that before..

 

as far as missing a closing one, one way to handle that is to do a quick preg_match_all count on both.  If they don't add up, throw an extra one one the end, or else remove one.  It will of course cause it to either not render one of them or else render too many, but I think that's the lesser of the two evils, as far as either that or having one left open...

The simple solution to nested BBCode tags is to handle the opening and closing tags individually; see this post.

 

brilliant! Haha why did I never think of that before..

 

as far as missing a closing one, one way to handle that is to do a quick preg_match_all count on both.  If they don't add up, throw an extra one one the end, or else remove one.  It will of course cause it to either not render one of them or else render too many, but I think that's the lesser of the two evils, as far as either that or having one left open...

 

My exact reaction when that guy pkSML first mentioned it ;D

 

And good idea counting the tags to see if they match. I would then simply throw an error message if the tags don't match up, as I see no reason why they shouldn't.

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.