<?php
error_reporting(-1);
mb_internal_encoding('utf-8');

$homoglyphs = [
    'У' => 'Y',
    'К' => 'K',
    'Е' => 'E',
    'Н' => 'H',
    'Х' => 'X',
    'В' => 'B',
    'А' => 'A',
    'Р' => 'P',
    'О' => 'O',
    'С' => 'C',
    'М' => 'M',
    'Т' => 'T',
    'у' => 'y',
    'е' => 'e',
    'х' => 'x',
    'а' => 'a',
    'р' => 'p',
    'о' => 'o',
    'с' => 'c'
];
$patternDummy = "/\\b%s\\b/ui";
$badWords = ["дурак", "тупица"];
$goodWords = ["молодец", "умница"];
$badText = "Ты дурак. Я - дУ Ра К. Он - дypaк. Она - Тyп и ц A!";

$patterns = array_map(
    fn($badWord) => sprintf($patternDummy, implode("\s*", array_map(
        fn($ch) => isset($homoglyphs[$ch]) ? "[$ch$homoglyphs[$ch]]" : $ch,
        mb_toArray($badWord)
    ))),
    $badWords
);

echo preg_replace($patterns, $goodWords, $badText);

function mb_toArray(string $s): array
{
    return preg_split("//u", $s, null, PREG_SPLIT_NO_EMPTY);
}
