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
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). 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.