2012-09-12 3 views
0

У меня проблема с preg_replace() с использованием массивов.preg_replace с двумя массивами

В принципе, я бы хотел транспонировать эту строку;

$string = "Dm F Bb F Am"; 

Для

$New_string = "F#m D D A C#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 ## м E # DE # E # M

Проблема в том, что каждое соответствие заменяется на следующее, что-то подобное происходит (например, для E ## м):

Dm -> F # м -> A # м -> C## м -> E ## м

Есть ли решение просто измените «Dm» на «F # m», «F» на «A» и т. д.?

Спасибо!

+2

Похоже на простое 'str_replace()' мне, нет 'preg' требуется – DaveRandom

+0

спасибо, но я уже пробовал с' str_replace() ', и результат точно такой же, это неправильно ... – SuN

+0

Oh * right * Я вижу к чему вы клоните. Ответит через секунду. – DaveRandom

ответ

4

Вы можете использовать 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 A D A C#m 
+0

Большое спасибо Михай, это трюк! – SuN

+0

Упрощенный больше, :) –

+2

Ах да, я забыл, что вы можете использовать отвертку для винтов вместо молотка. +1 – DaveRandom

1

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; 

See it working

Теперь я знаю, что приведенный выше код является немного непонятным, так что давайте разбить его немного и посмотреть, что каждый отдельный компонент делает:

// 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); 
Смежные вопросы