Проблема с заменой str_replace неправильных значений

#php

#php

Вопрос:

Я пытаюсь заменить список чисел (идентификаторов) на их связанный заголовок, проблема в том, что когда заголовок имеет номер, он также заменяется, например:

 $idlist = "1, 2, 3";

$a = array(17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
$b = array('Star Trek 7', 'Superman 8', 'Toy Story 2', 'Terminator 3', 'Other', 'Superman 4', 'Star Trek 3', 'Superman 3', 'Mad Max 3', 'Mad Max 2', 'Superman 3', 'Superman 2', 'Christmas Vacation 3', 'Star Trek 2', 'Terminator 2', 'Toy Story 3', 'Mission Impossible 2');

echo str_replace($a, $b, $idlist);
 

Неправильный текущий результат:

 Mission Impossible 2, Toy Story 3, Terminator Toy Story 3
 

Должно быть:

 Mission Impossible 2, Toy Story 3, Terminator 2
 

Что было бы лучшим способом сделать это?

Комментарии:

1. Создайте карту, ключами которой являются версия фильма, а значениями — текст. Затем используйте числа в первом массиве для поиска на карте.

2. Поведение этой функции описано в документации ( «Поскольку str_replace() заменяет слева направо, это может заменить ранее вставленное значение при выполнении нескольких замен.» ). Перейдите на страницу руководства str_replace и прочитайте примечания и примеры кода. Попробуйте другое решение, может быть, регулярные выражения?

Ответ №1:

Попробуйте strtr вместо этого str_replace :

 $idlist = "1, 2, 3";

$a = array(17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
$b = array('Star Trek 7', 'Superman 8', 'Toy Story 2', 'Terminator 3', 'Other', 'Superman 4', 'Star Trek 3', 'Superman 3', 'Mad Max 3', 'Mad Max 2', 'Superman 3', 'Superman 2', 'Christmas Vacation 3', 'Star Trek 2', 'Terminator 2', 'Toy Story 3', 'Mission Impossible 2');

$pairs = array_combine($a, $b);

echo strtr($idlist, $pairs);
 

Результат:

 Mission Impossible 2, Toy Story 3, Terminator 2
 

Комментарии:

1. Большое вам спасибо, Гусак, это решает мою проблему!

2. Теперь мне интересно, что ответ @mihai-matei все-таки правильный. Проблема появится, когда вы получите идентификаторы в другом порядке, и он найдет ключ 12 в идентификаторе 123 .

3. Но все должно быть в порядке, если я сохраню порядок от большего идентификатора до маленького идентификатора, верно?

4. Должно быть хорошо.

Ответ №2:

Вы можете просто объединить эти 2 массива и заменить список идентификаторов на preg_replace_callback:

 $array = array_combine($a, $b);

$result = preg_replace_callback('/(d )/', static function($matches) use ($array) {
    return $array[$matches[1]];
}, $idlist);

var_dump($result);
 

Комментарии:

1. Буквально минуту назад я понял, что вы дали лучший ответ. Ваш ответ должен быть решением.

Ответ №3:

Попробуйте создать список идентификаторов в виде массива целых чисел:

 $idlist = array(1, 2, 3);
 

Вместо «1, 2, 3» вы можете использовать:

 array($b[0], $b[1], ... $b[n]). 
 

С помощью этой формы вы можете заменить только имена в массиве $b, и имена будут автоматически меняться в списке массивов.

Редактировать:

Преобразуйте строку в массив:

 $ids = explode(",", $idlist);
 

И вы можете использовать массив как:

 $arrayNames = array($b[intval($ids[0])], $b[intval($ids[1])], ... $b[intval($ids[n])]). 
 

Комментарии:

1. Проблема в том, что списки идентификаторов уже созданы, я получаю эти списки идентификаторов из базы данных в виде строки…

2. Спасибо, МИСТЕР Марк II