I have some code like this, which replaces some shortcodes with a link:
$search = array(
'#\{r\|([^|]+)\|([^}]+)\}#',
'#\{t\|([^|]+)\|([^}]+)\}#',
...,
);
$replace = array(
'<a href="/ref/$1">$2</a>',
'<a href="/type/$1">$2</a>',
...,
);
$content = preg_replace( $search, $replace, $content );
I have lots more that are similar so I was wondering, is there some way to reduce this to one simple preg_replace with a conditional?
For example, use the regex #\{([a-z])\|([^|]+)\|([^}]+)\}# and replace the first match with something different (r=ref, t=type) based on its letter? (If it helps, the shortcodes are like {r|url-slug|LinkTitle}.)
This calls for preg_replace_callback (or possibly just the /e eval modifier), which would allow you to put the mapping t = type and r = ref in the replacement logic:
= preg_replace_callback('#\{([rt])\|([^|]+)\|([^}]+)\}#', "cb_123", ...
function cb_123($m) {
$map = array("t" => "type", "r" => "ref");
$what = $map[ $m[1] ];
return "<a href=\"/$what/$m[2]\">$m[3]</a>";
}
DISCLAIMER: What follows below is terrible advice, and suggests the use of a PHP feature that is quite rightly now deprecated. I'm only leaving it here for a historical reference.
Use the technique suggested in the accepted answer.
The alternative to the (perfectly valid) preg_replace_callback() method suggested by @mario is the e modifier, which is available only with preg_replace() and allows your replacement string to be evaluated as PHP code:
<?php
$shortCodes = array (
'r' => 'ref',
't' => 'type'
);
$expr = '#\{([a-z])\|([^|]+)\|([^}]+)\}#e';
$replace = '"<a href=\"/{$shortCodes[\'$1\']}/$2\">$3</a>"';
$string = 'Some text as a ref {r|link1.php|link} and a type {r|link2.php|link}';
echo preg_replace($expr, $replace, $string);
The only problem I can think of is if your LinkTitle contains a single quote it will be escaped and appear as \' in the output.
See it working
EDIT
After a little trial and error, here is a version that works with anything you can throw at it, and also passes all the data through urlencode()/htmlspecialchars() where appropriate:
<?php
$shortCodes = array (
'r' => 'ref',
't' => 'type'
);
$expr = array(
'#\{([a-z])\|([^|]+)\|([^}]*"[^}]*)\}#e',
'#\{([a-z])\|([^|]+)\|([^}]+)\}#e'
);
$replace = array(
'"<a href=\"/{$shortCodes[\'$1\']}/".htmlspecialchars(urlencode(\'$2\'))."\">".htmlspecialchars(str_replace(\'\"\', \'"\', \'$3\'))."</a>"',
'"<a href=\"/{$shortCodes[\'$1\']}/".htmlspecialchars(urlencode(\'$2\'))."\">".htmlspecialchars(\'$3\')."</a>"'
);
$string = 'Some text as a ref {r|link &1.php|link&\' with some bad characters in it} and a type {r|link2.php|link with some "quotes" in it}';
echo preg_replace($expr, $replace, $string);
Outputs:
Some text as a ref <a href="/ref/link+%261.php">link&' with some bad characters in it</a> and a type <a href="/ref/link2.php">link with some "quotes" in it</a>
See it working
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With