Как заставить функцию работать на пару слов?

Моя функция теперь работает только с одним словом. Например, у меня есть слова в ассоциативном массиве. И моя функция заменяет ключ массива его значением в тексте. И функция для сохранения слов в нижнем регистре, но при замене слов он вернет регистр входящего слова, который написан на тексте. Теперь функция не может работать с парами слов, чтобы заменить пары слов другими парами слов.

Пример:

// Function:

function replaceKeyToValue($request, $dict){
$response = preg_replace_callback("/\pL+/u", function ($m) use ($dict) {
$word = mb_strtolower($m[0]);
if (isset($dict[$word])) {
$repl = $dict[$word];
// Check for some common ways of upper/lower case
// 1. all lower case
if ($word === $m[0]) return $repl;
// 2. all upper case
if (mb_strtoupper($word) === $m[0]) return mb_strtoupper($repl);
// 3. Only first letters are upper case
if (mb_convert_case($word,  MB_CASE_TITLE) === $m[0]) return mb_convert_case($repl,  MB_CASE_TITLE);
// Otherwise: check each character whether it should be upper or lower case
for ($i = 0, $len = mb_strlen($word); $i < $len; ++$i) {
$mixed[] = mb_substr($word, $i, 1) === mb_substr($m[0], $i, 1)
? mb_substr($repl, $i, 1)
: mb_strtoupper(mb_substr($repl, $i, 1));
}
return implode("", $mixed);
}
return $m[0]; // Nothing changes
}, $request);
return $response;
}

// Example associative array

$dict = array
(
"make"=>"take",
"cool"=>"pool",
"узбек"=>"ӯзбек",
);

$text = 'Make COOL узБЕК';

echo replaceKeyToValue($text, $dict);

Выход:

Take POOL ӯзБЕК

Как будет переделана функция, чтобы она могла также объединять слова в пару слов?

Пример массива с парами слов:

$array = array
(
"take pool" => "pool take",
"get book" => "set word",
"узбек точик" => "ӯзбек тоҷик");

$example_text = "Take POOL Get BooK УзБеК ТоЧИК";

0

Решение

Во-первых, выньте свое преобразование из проблемы и напишите специальную функцию для его обработки.

О парах слов: Вы можете решить проблему, используя:

  • предвкушение с дополнительным подшаблоном для захвата второго слова
  • статический логическая переменная (определенная в функции обратного вызова), чтобы узнать, было ли предыдущее совпадение первым словом в существующей подстроке из двух слов.

Вам нужен только этот шаблон:

~\b\pL+\b(?=( \pL+\b)?)~u

Предварительный просмотр позволяет пройти строку при каждом начале слова (даже в конце строки, так как (?=( \pL+\b)?) является всегда верное утверждение.), поскольку он не потребляет никаких символов.

Это очень просто:

  • логическая переменная установлена ​​в false в начале.
  • когда логическое значение ложно и $m[0].$m[1] в нижнем регистре существует в ключах dict, затем установите логическое значение в true и вернуть значение dict, иначе вернуть $m[0]
  • когда логическое значение истинно, установите его в false и вернуть пустую строку

Преимущество: Вам не нужно заботиться о размере диктов. Используя ту же идею, вы можете даже расширить алгоритм на большее количество слов с небольшими изменениями или обработать указание, в котором ключи элементов имеют разное количество слов.

Совет: когда вы думаете, чтобы изменить предел возврата или построить гигантское чередование, не делайте этого. Это только означает, что ваш подход не очень хороший.

0

Другие решения

Других решений пока нет …