I agree with these guys, however since I have done similar things before I thought I would throw in my 2 cents to help. I am sure there are better ways, but here is one approach:
From what I can see you will not be able to do what youre trying to do without some functions (unless you are god of regexp). First, substitute the reserved bits, secondly make the changes and last, change back your substitutions.
Here is some pseudo code to get you going. Its based on stuff I have done before, but uncluttered and untested.
PHP Code:
function my_substitute($ref1, &$array)
{
static $i;
$i++;
$array[$i] = $ref1;
return "<<<@!$i!@>>>";
}
function my_unsubstitute($item, &$array)
{
return $array[$item];
}
function my_thang($find, $replace, &$text)
{
//This regexp should match [url] and [img] tags.
//We want to match them and call my_substitute on match,
$substitute = '%\\[[url|img]*([^\]]*)\](.*?)\[/[url|img]*\]%sime';
$subhandler = 'my_substitute(\'\1\', $subby)';
//this bit may not be needed, but it was a workaround for
//some glbalising issue. Just don't remember what issue that was
$subby = array();
$GLOBALS['subby'] = array();
$subby =& $GLOBALS['subby'];
//This replaces your url and img tags with placeholders
$text = preg_replace($substitute, $subhandler , $text);
//This bit is where you do whatever you were wanting to do
$text = preg_replace($find, $replace, $text);
//if there are subs, this bit replaces tokens back to what they were
if (sizeof($subby))
{