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