preg_replace with pattern array

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
pagod
Forum Newbie
Posts: 5
Joined: Wed Mar 05, 2008 10:59 am

preg_replace with pattern array

Post by pagod »

Hi,

i'm doing some automatic relinking of image tags in HTML pages in order to make the src addresses to these images absolute. in order to cover the various possibilities (absolute URI with server name, absolute path on server, relative path, and last but not least unquoted src), i'm using an array of source patterns, and an array of replacement strings. here's what the array looks like:

Code: Select all

 
$body = preg_replace(
    array( '!<img\s*([^>]*?)\s+src=(["\'])(/[^"\']+)\2!i', '!<img\s*([^>]*?)\s+src=(["\'])(http://[^"\']+)\2!i', '!<img\s*([^>]*?)src=(["\'])([^"\']+)\2!i', '!<img\s*([^>]*?)src=([^\'" ]+)!i' ),
    array( "<!-- 1 --><img $1 src=\"$protocol://$server$3\"", "<!-- 2 --><img $1 src=\"$3\"", "<!-- 3 --><img $1 src=\"$baseuri$3\"", "<!-- 4 --><img $1 src='$baseuri$2'" ),
    $body2 );
the problem i have is that the results of the replacements also match the patterns in the array, since it's only relinking. and apparently, PHP tries to iteratively match all elements in the array starting at the same position in the source string, and regardless of whether one pattern already matched! i must say i wasn't expecting that, i thought it would stop replace at a given position as soon as any of the source patterns would match, and then go on after the matched part!

so now i get results like the following:

Code: Select all

 
<!-- 1 -->
<!-- 2 -->
<!-- 3 -->
<img  src="http://www.google.com/http://www.google.com/images/logo_sm.gif" width=150 height=55 alt=Google border=0 vspace=12>
 
as the numbered comments show, the various patterns in the array have actually all (but one) been matched in turn at the same, already processed position in the source string.

so the first question is of course: is it really the way it's meant to be?? and my second question is, is there an easy way to prevent this? of course, i can simply write a loop that goes through the HTML code and applies only 1 replacement for each image, but i was just wondering how more experienced programmers would do...

thx in advance for your help!

pagod

PS: in case that might be relevant, i'm running PHP 5.2.6 (Zend Engine v2.2.0) on MacOS Leopard 10.5.6 (Intel) with Apache 2.2.9 installed.
pagod
Forum Newbie
Posts: 5
Joined: Wed Mar 05, 2008 10:59 am

Re: preg_replace with pattern array

Post by pagod »

actually by reworking on the source patterns themselves and the order in the array, i was able to prevent them from matching the destination patterns, thus also preventing multiple replacements.

however, this still doesn't answer the core question: is this behaviour normal (and if yes, what's the point?), and is there a way to prevent this and simply use the source pattern array as a collection of "independent" patterns of which only 1 is matched per position in the source string??

cheers,

pagod
Post Reply