I have a code that compares the output with the values of the array, and only terminates the operation with words in the array:
First code(just a example
Unfortunately strtr()
is the wrong tool for this job because it is "word boundary ignorant". To target whole words there is no simpler way that using a regex pattern with word boundaries.
Furthermore, to ensure that longer strings are match prior to shorter strings (strings that may exist inside other strings), you must sort $myWords
by string length (descending / longest to shortest; using the multi-byte version only if necessary).
Once the array of words is sorted and converted to individual regex patterns, you can feed the arrays into the pattern
and replace
parameters of preg_replace()
.
Code (Demo)
$myVar = "my sister alannis is not that blonde, here is a good place";
$myWords=array(
array("is","é"),
array("on","no"),
array("that","aquela"),
array("sister","irmã"),
array("my","minha"),
array("myth","mito"),
array("he","ele"),
array("good","bom"),
array("ace","perito")
);
usort($myWords,function($a,$b){return mb_strlen($b[0])<=>mb_strlen($a[0]);}); // sort subarrays by first column multibyte length
// remove mb_ if first column holds no multi-byte characters. strlen() is much faster.
foreach($myWords as &$words){
$words[0]='/\b'.$words[0].'\b/i'; // generate patterns using search word, word boundaries, and case-insensitivity
}
//var_export($myWords);
//var_export(array_column($myWords,0));
//var_export(array_column($myWords,1));
$myVar=preg_replace(array_column($myWords,0),array_column($myWords,1),$myVar);
echo $myVar;
Output:
minha irmã alannis é not aquela blonde, here é a bom place
What this doesn't do is appreciate the case of the matched substrings. I mean, my
and My
will both be replaced by minha
.
To accommodate different casing, you will need to use preg_replace_callback()
.
Here is that consideration (which handles uppercase first letter words, not ALL CAPS words):
Code (Demo) <-- run this to see the original casing preserved after the replacement.
foreach($myWords as $words){
$myVar=preg_replace_callback(
$words[0],
function($m)use($words){
return ctype_upper(mb_substr($m[0],0,1))?
mb_strtoupper(mb_substr($words[1],0,1)).mb_strtolower(mb_substr($words[1],1)):
$words[1];
},
$myVar);
}
echo $myVar;