PHP: preg_replace только первая соответствующая строка в массиве - PullRequest
0 голосов
/ 25 ноября 2018

Я начал с preg_replace в PHP, и мне интересно, как я могу заменить только первый соответствующий ключ массива указанным значением массива, потому что я установил preg_replace номер параметра изменений в '1', и он все равно меняется более одного раза.Я также разделил свою строку на отдельные слова и проверял их одно за другим:

<?php
  $internal_message = 'Hey, this is awesome!';

  $words = array(
     '/wesome(\W|$)/' => 'wful',
     '/wful(\W|$)/' => 'wesome',
     '/^this(\W|$)/' => 'that',
     '/^that(\W|$)/' => 'this'
  );

  $splitted_message = preg_split("/[\s]+/", $internal_message);
  $words_num = count($splitted_message);

  for($i=0; $i<$words_num; $i++) {
     $splitted_message[$i] = preg_replace(array_keys($words), array_values($words), $splitted_message[$i], 1);
  }

  $message = implode(" ", $splitted_message);
  echo $message;
?>

Я хочу, чтобы это было на выходе:

Эй, это ужасно

(смена одного суффикса, смена одного слова и остановки)

Не это:

Эй, это круто

(два изменения суффикса, два изменения слова и возврат к исходному слову и суффиксу ...)

Может быть, я могу упростить этот код?Я также не могу изменить порядок ключей и значений массива, потому что скоро будет больше суффиксов и отдельных слов.Я новичок в php-кодировании и буду благодарен за любую помощь;>

1 Ответ

0 голосов
/ 25 ноября 2018

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

$internal_message = 'Hey, this is awesome!';

$words = array(
    'wesome' => 'wful',
    'wful' => 'wesome',
    'this' => 'that',
    'that' => 'this'
);
$rx = '~(?:' . implode("|", array_keys($words)) . ')\b~';
echo "$rx\n";
$message = preg_replace_callback($rx, function($m) use ($words) {
    return isset($words[$m[0]]) ? $words[$m[0]] : $m[0];
}, $internal_message);
echo $message;
// => Hey, that is awful!

См. Демонстрационную версию PHP .

Регулярное выражение:

~(?:wesome|wful|this|that)\b~

(?:wesome|wful|this|that) - это группа без захвата, которая соответствуетлюбое из значений внутри, и \b является границей слова, непотребляющим шаблоном, который гарантирует отсутствие буквы, цифры или _ после суффикса.

preg_replace_callback анализирует строку один рази когда происходит совпадение, оно передается анонимной функции (function($m)) вместе с массивом $words (use ($words)), а если массив $words содержит найденный ключ (isset($words[$m[0]])), соответствующее значениевозвращается ($words[$m[0]]) или найденное совпадение возвращается в противном случае ($m[0]).

...