I like to replace the letters "KELLY" bettween "#" with the same length of "#". (here, repetitive five #'s instead of 'KELLY')
$str = "####KELLY#####"; // any alpabet letters can come.
preg_replace('/(#{3,})[A-Z]+(#{3,})/', "$1$2", $str);
It returns ######### (four hashes then five hashes) without 'KELLY'.
How can I get ############## which is four original leading hashes, then replace each letter with a hash, then the five original trailing hashes?
The \G continue metacharacter makes for a messier pattern, but it enables the ability to use preg_replace() instead of preg_replace_callback().
Effectively, it looks for the leading three-or-more hashes, then makes single-letter replacements until it reaches the finishing sequence of three-or-more hashes.
This technique also allows hash markers to be "shared" -- I don't actually know if this is something that is desired.
Code: (Demo)
$str = "####KELLY##### and ###ANOTHER###### not ####foo#### but: ###SHARE###MIDDLE###HASHES### ?";
echo $str . "\n";
echo preg_replace('/(?:#{3}|\G(?!^))\K[A-Z](?=[A-Z]*#{3})/', '#', $str);
Output:
####KELLY##### and ###ANOTHER###### not ####foo#### but: ###SHARE###MIDDLE###HASHES### ?
############## and ################ not ####foo#### but: ############################# ?
Breakdown:
/ #starting pattern delimiter
(?: #start non-capturing group
#{3} #match three hash symbols
| # OR
\G(?!^) #continue matching, disallow matching from the start of string
) #close non-capturing group
\K #forget any characters matched up to this point
[A-Z] #match a single letter
(?= #lookahead (do not consume any characters) for...
[A-Z]* #zero or more letters then
#{3} #three or more hash symbols
) #close the lookahead
/ #ending pattern delimiter
Or you can achieve the same result with preg_replace_callback().
Code: (Demo)
echo preg_replace_callback(
'/#{3}\K[A-Z]+(?=#{3})/',
function($m) {
return str_repeat('#', strlen($m[0]));
},
$str
);
I solved the problem with preg_replace_callback function in php. Thanks CBroe for the tips.
preg_replace_callback('/#{3,}([A-Z]+)#{3,}/i', 'replaceLetters', $str);
function replaceLetters($matches) {
$ret = '';
for($i=0; $i < strlen($matches[0]); $i++) {
$ret .= "#";
}
return $ret;
}