Go Back   CodingForums.com > :: Server side development > PHP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 03-04-2008, 02:57 AM   PM User | #1
qhiiyr
New Coder

 
Join Date: Jun 2006
Posts: 12
Thanks: 0
Thanked 0 Times in 0 Posts
qhiiyr is an unknown quantity at this point
problem with preg_replace()

Hello, I have a problem using preg_replace for my bbcode. I want it to search for a color (i.e. "Red", "Blue", etc.) in the URL it is turning into a link, and then make that link that color.

The bbcode links are formed like usual: [ url=http://mysite.com/]text[/url]

The problem occurs when I have two links, like this:

Code:
[ url=http://mysite.com/Red/page.php]Link 1[/url] blah blah blah [ url=http://mysite2.com/Green/page2.php]Link 2[/url]
What happens is that PHP thinks that everything from the first http to the end of the second URL is all one URL. To help explain:

[ url=http://mysite.com/Red/page.php]Link 1[/url] blah blah blah [ url=http://mysite2.com/Green/page2.php]Link 2[/url]

It thinks that all the orange in there is all one URL, so it makes one link with the href attribute being that entire orange blob of text.

My preg_replace code for that part is this:

PHP Code:
function parse($string) {
global 
$allcolors// contains all colors to match (Red, Blue, Green, etc.)
    
foreach($allcolors as $color) {
    
// colors links accordingly if they have one of our colors in their url
        
$preg_find[] = '/\[url\=(.*?)' $color '(.*?)\](.*?)\[\/url\]/is';
        
$preg_replace[] = '<a href="$1' $color '$2" style="color: ' $color ';">$3</a>';
// ... some more code for bbcode ...
$string preg_replace($preg_find$preg_replace$string);
return 
$string
I can't figure out how to avoid it! Any help or suggestions are appreciated much. Thanks!
qhiiyr is offline   Reply With Quote
Old 03-04-2008, 04:50 AM   PM User | #2
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
It works otherwise right? I reaaalllly don't want to do any pattern matching right now -_-.
Anyway, what you are experiencing is PHP's greedyness. Simple fix, on your pattern modifiers (ie: '/^a.../si' the 'si' are your modifiers), add a 'U' to tell PHP to not be greedy. By default, it will seek anything between the two possible options you are giving it, including more calls. Try that, see if that fixes if for you.
__________________
As of PHP 5.5, the MySQL library has been officially deprecated. It is recommended to move to either MySQLi or PDO libraries for your mysql connectivity. See here for help choosing which interface you prefer: http://php.net/manual/en/mysqlinfo.api.choosing.php
Fou-Lu is offline   Reply With Quote
Old 03-04-2008, 05:16 AM   PM User | #3
qhiiyr
New Coder

 
Join Date: Jun 2006
Posts: 12
Thanks: 0
Thanked 0 Times in 0 Posts
qhiiyr is an unknown quantity at this point
Just tried it, same exact thing happens.

It works fine when there is only one link. It also works fine when I comment out the color-related code and let the link be parsed as a normal link (the normal link code was not shown in my first post).

Out of curiosity I added the U to the normal link parsing, and commented out the color-related parsing to see what would happen, and it actually seemed like it did the opposite of the desired effect -- the same problem I initially had occurs (it thinks the URL is that huge blob of text), only with the normal link parsing and not the color parsing.

I'm not too familiar with the modifiers; is there a modifier that does the opposite of whatever U does? It seems like that might help.
qhiiyr is offline   Reply With Quote
Old 03-04-2008, 04:30 PM   PM User | #4
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
What I can tell you (after testing it), is its not a greedyness thing:
PHP Code:
function parse($string)
{
    
$allcolors = array('Red''Green');
    foreach(
$allcolors as $color) {
    
// colors links accordingly if they have one of our colors in their url
        
$preg_find[] = '/\[url\=(.*?)' $color '(.*?)\](.*?)\[\/url\]/is';
        
$preg_replace[] = '<a href="$1' $color '$2" style="color: ' $color ';">$3</a>';
// ... some more code for bbcode ...
    
}
$string preg_replace($preg_find$preg_replace$string);
return 
$string;  
}

$str "[url=http://mysite.com/Red/page.php]Link 1[/url] blah blah blah [url=http://mysite2.com/Green/page2.php]Link 2[/url]";

echo 
parse($str); 
This results in this:
Link 1 blah blah blah Link 2
Where link 1 goes to: http://myslite.com/Red/page.php and http://mysite2.com/Green/page2.php.
So this block of code itself is alright. I'm thinking the problem in this case is it is interfering with the already existing url tag built into the system. If this is the case, you can probably get around modifying it by placing this as a higher priority in replacement than the url tag. If that still doesn't work, you will need to change the url code to reflect the possibility of a colour addition.

Try those out, see if either of them fix the problem for you.
__________________
As of PHP 5.5, the MySQL library has been officially deprecated. It is recommended to move to either MySQLi or PDO libraries for your mysql connectivity. See here for help choosing which interface you prefer: http://php.net/manual/en/mysqlinfo.api.choosing.php
Fou-Lu is offline   Reply With Quote
Old 03-04-2008, 04:56 PM   PM User | #5
qhiiyr
New Coder

 
Join Date: Jun 2006
Posts: 12
Thanks: 0
Thanked 0 Times in 0 Posts
qhiiyr is an unknown quantity at this point
Okay, after some testing I've figured out what the problem is, but I don't know how to fix it.

The code block you gave me only works when the colors in the array are in the same order as the links in the string. So if you change the array from
PHP Code:
$allcolors = array('Red''Green'); 
to
PHP Code:
$allcolors = array('Green''Red'); 
it doesn't work anymore.
qhiiyr is offline   Reply With Quote
Old 03-04-2008, 07:21 PM   PM User | #6
Inigoesdr
Super Moderator


 
Inigoesdr's Avatar
 
Join Date: Mar 2007
Location: Florida, USA
Posts: 3,601
Thanks: 2
Thanked 397 Times in 390 Posts
Inigoesdr is a jewel in the roughInigoesdr is a jewel in the roughInigoesdr is a jewel in the rough
Here, try this:
PHP Code:
function parse($string)
{
    
$allcolors = array('Red''Green''Black'); // this is set elsewhere, apparently
    
$allcolors = !empty($allcolors) ? implode('|'$allcolors) : 'Red'// make sure allcolors always has a value
    
$replace = array('~\[url=(https?://.*?/)(' $allcolors ')(/.*?)\](.*?)\[/url\]~si' => '<a href="\\1\\2\\3" style="color: \\2;">\\4</a>');
    
$string preg_replace(array_keys($replace), array_values($replace), $string);
    return 
$string;  
}

$str "[url=http://mysite.com/Red/page.php]Link 1[/url] blah blah blah [url=http://mysite2.com/Green/page2.php]Link 2[/url] blah blah blah [url=http://mysite2.com/Black/page2.php]Link 3[/url]";

echo 
parse($str); 
I changed the delimiter to a tilde to avoid having to escape all of the forwardslashes.

If you're only doing the color replace on the string you don't really need a function(or array of the replacements), unless you're replacing the same thing in multiple strings. If it's just one you can do something like this:
PHP Code:
$str "[url=http://mysite.com/Red/page.php]Link 1[/url] blah blah blah [url=http://mysite2.com/Green/page2.php]Link 2[/url] blah blah blah [url=http://mysite2.com/Black/page2.php]Link 3[/url]";
$allcolors = array('Red''Green''Black'); // this is optional, and set elsewhere, apparently
$allcolors = !empty($allcolors) ? implode('|'$allcolors) : 'Red'// make sure allcolors always has a value
$string preg_replace('~\[url=(https?://.*?/)(' $allcolors ')(/.*?)\](.*?)\[/url\]~si''<a href="\\1\\2\\3" style="color: \\2;">\\4</a>'$str);
echo 
$string
Inigoesdr is offline   Reply With Quote
Old 03-05-2008, 12:50 AM   PM User | #7
qhiiyr
New Coder

 
Join Date: Jun 2006
Posts: 12
Thanks: 0
Thanked 0 Times in 0 Posts
qhiiyr is an unknown quantity at this point
Awesome! Had to change it a little, but it works perfect! Thanks a bunch!

Oh, and I actually did need to use it in a function, because I have a big parse function for parsing all text that needs to, well, be parsed, and this was only a small piece of it.

Thanks so much again!
qhiiyr is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

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

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 12:54 PM.


Advertisement
Log in to turn off these ads.