TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 04-05-2008, 09:47 PM   #1 (permalink)
The Contributor
 
mortisimus's Avatar
 
Join Date: Sep 2007
Location: London, UK
Posts: 47
Thanks: 4
mortisimus is on a distinguished road
Default BBCode using Preg_Replace

Ok guys, it's been a while since I've posted here and about a year since I've written any tutorials. I had a look around and couldn't find any tutorials on this so sorry if it's a repost.

Anyway, I was digging around in my old scripts and found a bbcode function so I guess I'll teach you guys if you want to learn it

Right, bbcode is basically created by matching a regular expression and then replacing it with something new (see: PHP: preg_replace - Manual).

For running bbcode on a string, we will create a function called bbcode.

PHP Code:
function bbcode$input ) {


The only parameter, input will be used as the subject for the replacing of regex.

Now we will create an array of strings so that we can match something and replace! To start off simple, we will only create one. The code below goes in your function.

PHP Code:
//the pattern to be matched
$pattern[0] = "/\[b\](.*?)\[\/b\]/is";
//the replacement
$replace[0] = "<strong>$1</strong>";
//the variable for the replace
$bbcoded preg_replace($pattern$replace$input);
//echo it out
echo $bbcoded
What's going on? Ok, the $pattern variable is an array so, [0] is added on the end to show what part of the array it is, the same applies to the $replace variable.

In the string for the pattern, a / is added at the start and the end of the string to be used as a delimeter to show what you are searching for. By convention, this is a / but it can be any character, note: the delimters at the start and the end MUST be the same.

The \ is used to escape php using these characters as code. In this case, in front of the / and the [ ].

In the pattern variable, you may notice a (.*?), this is a wildcard and is used to match any string that may be placed here. The ? on the end is lazy regex which basiccally means it will match something as little times as possible. The i on the end of the string makes the match case insensitive (Source: delayedinsanity). The s after the i is there to match new lines/line breaks. (Source: Nor).

In the replace variable, you may notice a $1, this is used to capture whatever is inside the first set of parentheses.

The $bbcoded variable is simple the replacement. preg_replace's parameters work like: mixed regex, mixed replacement, mixed subject. in this case, $pattern is the regex, $replace is the replacement and $input is the subject.

The last thing to do is echo out the replacement:
PHP Code:
echo $bbcoded
So the full function is:
PHP Code:
function bbcode$input ){
    
$pattern[0] = "/\[b\](.*?)\[\/b\]/i";
    
$replace[0] = "<strong>$1</strong>";
    
$bbcoded preg_replace($pattern$replace$input);
    echo 
$bbcoded;

Taking it further
Of course you can put more search and replacements in here because the variables for regex and replacement are arrays. Please note that if you add more in, the $pattern variable arrays will have to be under each other in ascending order and then the $replace variables can be written. For example:

PHP Code:
$pattern[0] = "/blah/";
$pattern[1] = "/blah/";
$pattern[2] = "/blah/";
$pattern[3] = "/blah/";
$replace[0] = "bloo";
$replace[1] = "bloo";
$replace[2] = "bloo";
$replace[3] = "bloo"
If you do not wish to do this, add the following lines before the preg_replace call:

PHP Code:
ksort($pattern);
ksort($replace);
//then preg_replace here 
Also, the preg_replace does not have to be assigned to a variable, it can just be echoed out.

Other examples:

PHP Code:
//URL's
$pattern[0] = "/\[url\=(.*)\](.*)\[\/url\]/i";
$replace[0] = "<a href=\"$1\">$2</a>";
echo 
preg_replace($pattern$replace$subject); 
Thanks for reading,
If you have any questions just ask

Example of Usage

Thanks for all the tips guys!

Last edited by mortisimus : 04-11-2008 at 03:11 PM.
mortisimus is offline  
Reply With Quote
The Following 2 Users Say Thank You to mortisimus For This Useful Post:
Orc (04-06-2008), Wildhoney (04-06-2008)
Old 04-06-2008, 08:18 AM   #2 (permalink)
The Contributor
RegEx Guru 
 
Join Date: Dec 2007
Location: Belgium
Posts: 60
Thanks: 6
Geert is on a distinguished road
Default

What happens if my subject string is...

Code:
[ B]Bold with capital B tags[/b]
Code:
[ b]bold[/b] not bold [ b]bold again[/b]
Code:
[ url=alert('boo!')]javascript?[/url]
__________________
Kohana - PHP5 framework
Geert is offline  
Reply With Quote
Old 04-06-2008, 09:21 AM   #3 (permalink)
Orc
The Prestige
 
Orc's Avatar
 
Join Date: Dec 2007
Posts: 1,044
Thanks: 193
Orc is on a distinguished road
Default

Thanks, Regular Expressions always get the best of me.
__________________
VillageIdiot can have my babbies ;d
Orc is offline  
Reply With Quote
Old 04-06-2008, 09:23 AM   #4 (permalink)
Orc
The Prestige
 
Orc's Avatar
 
Join Date: Dec 2007
Posts: 1,044
Thanks: 193
Orc is on a distinguished road
Default

Quote:
Originally Posted by Geert View Post
What happens if my subject string is...

Code:
[ B]Bold with capital B tags[/b]
Code:
[ b]bold[/b] not bold [ b]bold again[/b]
Code:
[ url=alert('boo!')]javascript?[/url]
for one thing in the [url] you should have done Javascript
__________________
VillageIdiot can have my babbies ;d
Orc is offline  
Reply With Quote
Old 04-06-2008, 09:37 AM   #5 (permalink)
The Contributor
 
mortisimus's Avatar
 
Join Date: Sep 2007
Location: London, UK
Posts: 47
Thanks: 4
mortisimus is on a distinguished road
Default

For capitals, you will need to add an extra variable:

PHP Code:
$lower strtolower($input); 
And then set $lower as the input, so your new code would be:
PHP Code:
function bbcode($input){
    
//lower the string to non-capitals
    
$lower strtolower($input);
    
    
$pattern[0] = "/\[b\](.*)\[\/b\]/";
    
$pattern[1] = "/\[url\=(.*)\](.*)\[\/url\]/";
    
    
$replace[0] = "<strong>$1</strong>";
    
$replace[1] = "<a href=\"$1\">$2</a>";
        
// your new subject is the string all lower case
    
$bbcoded preg_replace($pattern$replace$lower);
    echo 
$bbcoded;
}
codeBB("[b]hello![/b] [url=http://www.php.net/]PHP[/url]"); 
However, this will mean that you will have no capitals at all in your string. One moment while I work this out please. Of course you could just put in new rules for uppercase but I am fairly sure there is something to cut time.

Code:
[ b]bold[/b] not bold [ b]bold again[/b]
I would have to say that the best way to tackle this is create a seperate match for [ b] and [/b], for example:

PHP Code:
$pattern[0] = "/\[b\]/";
$pattern[1] = "/\[\/b\]/";
$replace[0] = "<strong>";
$replace[1] = "</strong>";

preg_replace($pattern$replace$input); 
mortisimus is offline  
Reply With Quote
Old 04-06-2008, 10:40 AM   #6 (permalink)
Orc
The Prestige
 
Orc's Avatar
 
Join Date: Dec 2007
Posts: 1,044
Thanks: 193
Orc is on a distinguished road
Default

By viewing this, you got me more into regular expressions, thus just now I made something where it validates Emails fully instead of filter_var! :D
__________________
VillageIdiot can have my babbies ;d
Orc is offline  
Reply With Quote
Old 04-06-2008, 02:09 PM   #7 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

"However, this will mean that you will have no capitals at all in your string."

Why not just do a case insensitive search by adding "i" to the end of your regular expression?

/\[b\](.*)\[\/b\]/i

Or worst come to worst, you should be able to group them.

/\[[Bb]\](.*)\[\/[Bb]\]/

Your new code with both possibilities would look like this:

PHP Code:
function bbcode($input){
    
$pattern[0] = "/\[[Bb]\](.*)\[\/[Bb]\]/";
    
$pattern[1] = "/\[url\=(.*)\](.*)\[\/url\]/i";
    
    
$replace[0] = "<strong>$1</strong>";
    
$replace[1] = "<a href=\"$1\">$2</a>";

    echo 
preg_replace($pattern$replace$input);
}
bbcode("[b]hello![/b] [url=http://localhost/]LOCALHOST!![/url]"); 
(note: not sure why, but the first B and last URL are capitalized on my end, but they get lowercased on output)
delayedinsanity is offline  
Reply With Quote
The Following User Says Thank You to delayedinsanity For This Useful Post:
Orc (04-06-2008)
Old 04-06-2008, 05:47 PM   #8 (permalink)
The Contributor
RegEx Guru 
 
Join Date: Dec 2007
Location: Belgium
Posts: 60
Thanks: 6
Geert is on a distinguished road
Default

Quote:
Originally Posted by mortisimus View Post
Code:
[ b]bold[/b] not bold [ b]bold again[/b]
I would have to say that the best way to tackle this is create a seperate match for [ b] and [/b]
I'll teach you a new regex trick. Lazy (opposite of greedy) matching. Matches as less as possible.

#\[b\](.*?)\[/b\]#i
__________________
Kohana - PHP5 framework
Geert is offline  
Reply With Quote
The Following 3 Users Say Thank You to Geert For This Useful Post:
delayedinsanity (04-07-2008), mortisimus (04-08-2008), Orc (04-07-2008)
Old 04-07-2008, 12:10 AM   #9 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

"I'll teach you a new regex trick. Lazy (opposite of greedy) matching. Matches as less as possible."

I've seen this before, but I keep forgetting about it. It actually solves a problem I asked about here awhile ago, if I were still using a regex for it - since then I've discovered I could use strpos() and substr() to accomplish it quicker.

Next thing I need to learn with regular expressions is assertions and I'll almost be ready to call myself a beginner with them.
-m
delayedinsanity is offline  
Reply With Quote
Old 04-07-2008, 03:26 AM   #10 (permalink)
Orc
The Prestige
 
Orc's Avatar
 
Join Date: Dec 2007
Posts: 1,044
Thanks: 193
Orc is on a distinguished road
Default

Could someone tell me how to make a indented preg replacing match, cause if you have indentation in replacing, and the string you're replacing it all off not like what it shows, then it screws me up. Im trying to make a syntax highlighter for C and Java
__________________
VillageIdiot can have my babbies ;d
Orc is offline  
Reply With Quote
Old 04-07-2008, 03:35 AM   #11 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

"\t" is the special character for tabs, so you could do something like

/\t+?(.*)/

perhaps, or if it's a specific amount of whitespace, such as 4 spaces, maybe

/\s{4}(.*)/

etc... does this help at all? The (.*) would be replaced with whatever else you're attemping to match, of course.
-m
delayedinsanity is offline  
Reply With Quote
Old 04-07-2008, 03:46 AM   #12 (permalink)
Orc
The Prestige
 
Orc's Avatar
 
Join Date: Dec 2007
Posts: 1,044
Thanks: 193
Orc is on a distinguished road
Default

Quote:
Originally Posted by delayedinsanity View Post
"\t" is the special character for tabs, so you could do something like

/\t+?(.*)/

perhaps, or if it's a specific amount of whitespace, such as 4 spaces, maybe

/\s{4}(.*)/

etc... does this help at all? The (.*) would be replaced with whatever else you're attemping to match, of course.
-m

Well its the problem of a persons indentation, I've been wanting ot make a syntax highlighter, but if someone has sloppy indentation, I can't do a successful pattern replacement, it just turns black v_v.

Unless, I do separate pattern matches for each set of keywords for syntax like "if condition then else", well I could chunk it out for pattern matching :D
__________________
VillageIdiot can have my babbies ;d
Orc is offline  
Reply With Quote
Old 04-07-2008, 03:50 AM   #13 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

Are you looping through it all line by line? If it's looking for it at the start of the line, try /^\s*(restofpattern)/ ... the ^ is the start of the string, \s is whitespace, and * is for 0 or more.
-m
delayedinsanity is offline  
Reply With Quote
Old 04-07-2008, 03:53 AM   #14 (permalink)
Orc
The Prestige
 
Orc's Avatar
 
Join Date: Dec 2007
Posts: 1,044
Thanks: 193
Orc is on a distinguished road
Default

Quote:
Originally Posted by delayedinsanity View Post
Are you looping through it all line by line? If it's looking for it at the start of the line, try /^\s*(restofpattern)/ ... the ^ is the start of the string, \s is whitespace, and * is for 0 or more.
-m
err say that I have a one line code
PHP Code:
 $string "Hello World!"
for the pattern replacement, and I give this code to replace
PHP Code:
$string 
"Hello World"
It then turns to black characters, how can I fix this?
__________________
VillageIdiot can have my babbies ;d
Orc is offline  
Reply With Quote
Old 04-07-2008, 03:56 AM   #15 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

I'm not sure if you copied the right code into the first segment there, they're both showing up as $string = "Hello World!"; and that confuses me... and when I get confused, I... ergh... aaah, it's happening... *turns into the Hulk*
delayedinsanity is offline  
Reply With Quote
Old 04-07-2008, 03:58 AM   #16 (permalink)
Orc
The Prestige
 
Orc's Avatar
 
Join Date: Dec 2007
Posts: 1,044
Thanks: 193
Orc is on a distinguished road
Default

Quote:
Originally Posted by delayedinsanity View Post
I'm not sure if you copied the right code into the first segment there, they're both showing up as $string = "Hello World!"; and that confuses me... and when I get confused, I... ergh... aaah, it's happening... *turns into the Hulk*
Well, I tried cutting them into pieces, so hang on, lemme do this.
__________________
VillageIdiot can have my babbies ;d
Orc is offline  
Reply With Quote
Old 04-07-2008, 04:06 AM   #17 (permalink)
Orc
The Prestige
 
Orc's Avatar
 
Join Date: Dec 2007
Posts: 1,044
Thanks: 193
Orc is on a distinguished road
Default

Well, I got it but isn't the best to do it, cause I want this to allow people to have syntax highlighters. -_-
__________________
VillageIdiot can have my babbies ;d
Orc is offline  
Reply With Quote
Old 04-07-2008, 04:14 AM   #18 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

I like doing all my code myself from the ground up, but if it helps, maybe check out something like this and see how they go about it. Good for ideas.
delayedinsanity is offline  
Reply With Quote
The Following User Says Thank You to delayedinsanity For This Useful Post:
Orc (04-07-2008)
Old 04-07-2008, 04:43 AM   #19 (permalink)
Orc
The Prestige
 
Orc's Avatar
 
Join Date: Dec 2007
Posts: 1,044
Thanks: 193
Orc is on a distinguished road
Default

Hey, how cna you do multple preg replaces in one string? Say like:
PHP Code:
$preg "/(echo|print.*?)\"(.*?)\"/"
This is saying we want to rpelace echo or print with whatever else with $1|$2, and then the other one is saying we want ot make the encapsulated quotation marked strings ( lol ) to become grey
__________________
VillageIdiot can have my babbies ;d
Orc is offline  
Reply With Quote
Old 04-07-2008, 12:25 PM   #20 (permalink)
Orc
The Prestige
 
Orc's Avatar
 
Join Date: Dec 2007
Posts: 1,044
Thanks: 193
Orc is on a distinguished road
Default

Okay, I tried my own [url], and it messed up if there are two url bbcodes in the place.

PHP Code:
        
                $bbcode 
= array( 
        
'urlRegex' => "/\[url=(.*)\](.*)\[\/url\]/",
        
'urlReplace' => '<a href="$1" class="url">$2</a>'
);
[/
url


I get this:
[code]
<a href="http://www.google.com]google
and [url=http://www.google.com" class="url">Google</a>
[/code]
__________________
VillageIdiot can have my babbies ;d
Orc is offline  
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 11:30 AM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design