str_replace () with foreach, uppercase and exact word matches

My code is:

$db = &JFactory::getDBO();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('old', 'new')))
      ->from($db->quoteName('#__words'));
$db->setQuery($query);
$results = $db->loadAssocList();
$find = array();
$replace = array();
foreach ($results as $row) {
 $find[] = $row['old'];
 $replace[] = $row['new'];
}
$newstring = str_replace($find, $replace, $oldstring);
echo $newstring;

This code replaces all words from the "old" column with words from the "new" column. But there are two problems. At first it works if the found and replaced words have the same case (upper or lower), but I need it to work regardless of case, i.e. The database has only lower case, but if the search word on the external interface has upper case, the replaced word should also have capital letters. Secondly, I need an exact word match. Thank you in advance!

+4
source share
1 answer

Try something like this:

$oldstring = 'The cat and the dog are flying into the kitchen. Dog. Cat. DOG. CAT';

$results = array( array('old'=>'cat', 'new'=>'chat'), array('old'=>'dog', 'new'=>'chien'));
foreach ($results as $row) {
    $fndrep[$row['old']] = $row['new'];
}

$pattern = '~(?=([A-Z]?)([a-z]?))\b(?i)(?:'
 // cyrillic => '~(?=([\x{0410}-\x{042F}]?)([\x{0430}-\x{044F}]?))\b(?i)(?:'
         . implode('|', array_keys($fndrep))
         . ')\b~';  // cyrillic => ')\b~u';

$newstring = preg_replace_callback($pattern, function ($m) use ($fndrep) {
    $lowm = $fndrep[strtolower($m[0])];
    if ($m[1])
        return ($m[2]) ? ucfirst($lowm) : strtoupper($lowm);
    else
        return $lowm;
}, $oldstring);

echo $newstring;  
+2

Source: https://habr.com/ru/post/1524871/


All Articles