У меня проблема с preg_replace()
с использованием массивов.
В принципе, я бы хотел транспонировать эту строку;
$string = "Dm F Bb F Am";
к
$New_string = "F#m DDAC#m";
Вот что я делаю:
$Find = Array("/Dm/", "/F/", "/Bb/", "/Am/", "/Bbm/", "/A/", "/C/"); $Replace = Array('F#m', 'A', 'D', 'C#m', 'Dm', 'C#', 'E'); $New_string = preg_replace($Find, $Replace, $string);
Но вместо этого я получаю этот результат:
E ## m E # DE # E # m
Проблема в том, что каждое соответствие заменяется следующим: что-то вроде этого (пример для E ## m):
Dm -> F # m -> A # m -> C ## m -> E ## m
Есть ли какое-либо решение просто изменить «Dm» на «F # m», «F» на «A» и т. Д.?
Спасибо !
Вы можете использовать strtr () :
<?php $string = "Dm F Bb F Am"; $Find = Array('Dm', 'F', 'Bb', 'Am', 'Bbm', 'A', 'C'); $Replace = Array('F#m', 'A', 'D', 'C#m', 'Dm', 'C#', 'E'); $New_string = strtr($string, array_combine($Find, $Replace)); echo $New_string; // F#m ADAC#m
preg_replace_callback()
, вероятно, самый простой способ сделать это, вам нужно сделать это за одну операцию. Что-то вроде этого:
<?php $string = "Dm F Bb F Am"; $replacements = array ( 'Dm' => 'F#m', 'F' => 'A', 'Bb' => 'D', 'Am' => 'C#m', 'Bbm' => 'Dm', 'A' => 'C#', 'C' => 'E' ); $New_string = preg_replace_callback('/\b('.implode('|', array_map('preg_quote', array_keys($replacements), array_fill(0, count($replacements), '/'))).')\b/', function($match) use($replacements) { return $replacements[$match[1]]; }, $string); echo $New_string;
Посмотрите, как работает
Теперь я знаю, что приведенный выше код немного непонятен, поэтому давайте немного разобьем его и посмотрим, что делает каждый отдельный компонент:
// The input string and a map of search => replace $string = "Dm F Bb F Am"; $replacements = array ( 'Dm' => 'F#m', 'F' => 'A', 'Bb' => 'D', 'Am' => 'C#m', 'Bbm' => 'Dm', 'A' => 'C#', 'C' => 'E' ); // Get a list of the search strings only $searches = array_keys($replacements); // Fill an array with / characters to the same length as the number of search // strings. This is required for preg_quote() to work properly $delims = array_fill(0, count($searches), '/'); // Apply preg_quote() to each search string so it is safe to use in the regex $quotedSearches = array_map('preg_quote', $searches, $delims); // Build the regex $expr = '/\b('.implode('|', $quotedSearches).')\b/'; // Define a callback that will translate search matches to replacements $callback = function($match) use($replacements) { return $replacements[$match[1]]; }; // Do the replacement $New_string = preg_replace_callback($expr, $callback, $string);