preg_replace с двумя массивами

У меня проблема с 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» и т. Д.?

Спасибо !

Related of "preg_replace с двумя массивами"

Вы можете использовать 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);