Forum Moderators: coopster

Message Too Old, No Replies

regex - only change last occurence

         

tomda

7:25 pm on Mar 29, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



This regex only change the last occurence ? Spent two many hours on this :(
Thank you



function get_colors() {
$colors = array('#FF66CC', '#FF6600', '#660033', '#6600CC', '#FF00CC', '#333300', '#9966CC', '#FF0000', '#009900', '#3366CC');
shuffle($colors);
return $colors[0];
}


$output = "<a href='http://l/w/tag/A/' class='tag-link-194' title='1 sujet' style='font-size: 90%;'>A</a> <a href='http://l/w/tag/B/' class='tag-link-72' title='2 sujets' style='font-size: 98.526315789474%;'>B</a> <a href='http://l/w/tag/C/' class='tag-link-415' title='6 sujets' style='font-size: 116.05263157895%;'>C</a>";

$pattern = '/<a href=\'([^"]*)\/([^"]*)\/\' class=\'tag-link-\d+\' title=\'(\d+) \w+\' style=\'font-size:\s(\d+)\.(\d+)%;\'>(\w+)<\/a>/i';

$replace = '<a href=\'$1/$2/\' onclick="javascript:ajaxpage(\''.WPURL.'/ajax-loop/\', \'post\', \'?slug=$2&type=tag\'); return false;" title="$3 articles" style="font-size:$4%; cursor:crosshair;"><span style="color:'.get_colors().'">$6</span></a>';

$output = preg_replace($pattern, $replace, $output) . PHP_EOL;

echo $output;

coopster

5:15 pm on Mar 30, 2011 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I don't have time to help refine the regex, but I can tell you that your pattern(s) are getting too greedy. Try adding the Ungreedy modifier (U) and I threw in the multiline too. Oh, I did notice that your font sizes won't match either when there is no decimal place (such as in your first link example of 90%) so I modified the capturing expression too:

$pattern = '/<a href=\'([^"]*)\/([^"]*)\/\' class=\'tag-link-\d+\' title=\'(\d+) \w+\' style=\'font-size:\s(\d+(\.\d+)?)%;\'>(\w+)<\/a>/Uis';

tomda

11:56 am on Mar 31, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thank you very much Coopster !
Great help !

Don't do much regex so never heard or greedy and Ungreedy modifier but did some search and I have refine the regex.

Yes, I noticed the 90% issue :)

Did you notice I have placed a function in the replace to randomly colorise words; but it doesn't work. Any idea how to add random value in PHP in the $replace statement ?

Or should I start another thread ?

Thank you

Here is the code
$colors = array('#FF66CC', '#FF6600', '#660033', '#6600CC', '#FF00CC', '#333300', '#9966CC', '#FF0000', '#009900', '#3366CC');

function get_colors() {
global $colors;
shuffle($colors);
return $colors[0];
}

$output = "<a href='http://www.example.com/tag/A/' class='tag-link-194' title='1 sujet' style='font-size: 90%;'>A</a> <a href='http://localhost/www.example.com/tag/B/' class='tag-link-72' title='2 sujets' style='font-size: 98.526315789474%;'>B</a>";

$pattern = '/<a href=\'http\:[\/]{2}(|\w+\/)([\w\.]+)\/tag\/(\w+)\/\' class=\'tag-link-\d+\' title=\'(\d+) \w+\' style=\'font-size:\s(\d+)(|\.\d+)%;\'>(\w+)<\/a>/i';

$replace = '<a href="http://$1/$2/tag/$3/" onclick="javascript:ajaxpage(\''.WPURL.'/ajax-loop/\', \'post\', \'?slug=$3&type=tag\'); return false;" title="$4 articles" style="font-size:$5%; cursor:crosshair;"><span style="color:'.get_colors().'">$7 (color:'.get_colors().')</span></a>';

$output = preg_replace($pattern, $replace, $output) . PHP_EOL;

echo $output;

tomda

12:27 pm on Mar 31, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Can't believ I found the solution. I used preg_replace_callback as follow and it works !


$colors = array('#FF66CC', '#FF6600', '#660033', '#6600CC', '#FF00CC', '#333300', '#9966CC', '#FF0000', '#009900', '#3366CC');

function get_colors() {
global $colors;
shuffle($colors);
return $colors[0];
}

$input = "<a href='http://www.example.com/tag/A/' class='tag-link-194' title='1 sujet' style='font-size: 90%;'>A</a> <a href='http://localhost/www.example.com/tag/B/' class='tag-link-72' title='2 sujets' style='font-size: 168.526315789474%;'>B</a> <a href='http://www.example.com/tag/C/' class='tag-link-194' title='1 sujet' style='font-size: 90%;'>C</a> <a href='http://localhost/www.example.com/tag/D/' class='tag-link-72' title='2 sujets' style='font-size: 298.526315789474%;'>D</a> <a href='http://www.example.com/tag/E/' class='tag-link-194' title='1 sujet' style='font-size: 90%;'>E</a> <a href='http://localhost/www.example.com/tag/F/' class='tag-link-72' title='2 sujets' style='font-size: 198.526315789474%;'>F</a>";

function parseTagsRecursive($input) {

$pattern = '/<a href=\'http\:[\/]{2}(|\w+\/)([\w\.]+)\/tag\/(\w+)\/\' class=\'tag-link-\d+\' title=\'(\d+) \w+\' style=\'font-size:\s(\d+)(|\.\d+)%;\'>(\w+)<\/a>/i';

if (is_array($input)) {
$input = '<a href="http://'.$input[1].'/'.$input[2].'/tag/'.$input[3].'/" onclick="javascript:ajaxpage(\''.WPURL.'/ajax-loop/\', \'post\', \'?slug='.$input[3].'&type=tag\'); return false;" title="'.$input[4].' articles" style="font-size:'.$input[5].'%; cursor:crosshair;"><span style="color:'.get_colors().'">'.$input[7].'</span></a>';
}

return preg_replace_callback($pattern, 'parseTagsRecursive', $input);
}

echo parseTagsRecursive($input);



Thank you

coopster

12:35 pm on Mar 31, 2011 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Good for you!
Yes, a callback is one way to get the job done. Another way is to write the replacement string with executable PHP code "built-in" and then use yet another modifier, the "e" modifier which evaluates the replacement string as PHP code.

modifiers [php.net]
preg_replace (see Example 4) [php.net]