2013-05-28 3 views
1

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

PHP-WAY:

$find = array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"); 
$replace = array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p"); 
$haystack = "a5c9a06bfacf5f12cf01ab3f202f6c78" 

//This incorrectly returns: kpmjkkglpkmppplmmpklklnpmkmpgmhi 
echo str_replace($find, $replace, $haystack); 

LOOP ПУТЬ:

$find = array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"); 
$replace = array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p"); 
$haystack = "a5c9a06bfacf5f12cf01ab3f202f6c78" 

//This correctly returns: kfmjkaglpkmpfpbcmpabkldpcacpgmhi 
$newStr = ""; 
$chars = str_split($haystack); 
for ($i = 0, $length = count($chars); $i < $length; $i++) 
{ 
    $newStr .= $replace[ array_search($chars[ $i ], $find) ]; 
} 
echo $newStr; 

Почему первый один неправильный? Я использую это неправильно?

+1

Порядок записей в ваших массивах .... str_replace() будет обрабатывать каждую запись массива в том порядке, в котором они отображаются в вашем массиве, поэтому, если «1» заменяется на «b», тогда это «b» будет впоследствии замените на «l»; используйте strtr() (http://uk3.php.net/manual/en/function.strtr.php), а не str_replace(), если вы хотите предотвратить это поведение. –

+0

Спасибо, добавлено как ответ ниже! –

ответ

3

Порядок записей в ваших массивах .... str_replace() будет обрабатывать каждую запись массива в том порядке, в каком они появляются в вашем массиве, поэтому, если «1» заменяется на «b», тогда это «b» впоследствии будет заменено с 'l'; используйте strtr(), а не str_replace(), если вы хотите предотвратить это поведение.

$find = array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"); 
$replace = array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p"); 
$haystack = "a5c9a06bfacf5f12cf01ab3f202f6c78" ; 
echo strtr($haystack, array_combine($find, $replace)); 

Ваш собственный код только делает один заменить, потому что это зацикливание против вашей строки, а не против от/к массивам.

+0

Можете ли вы добавить пример кода (который я добавил в своем ответе)? Тогда я помету ваш в качестве ответа. Благодарю. –

0

Как указано @MarkBaker, ответ заключается в том, что str_replace не просто перемещается вперед в строке, а вместо этого работает как рекурсивный .replace(). Вместо этого используйте strtr (что эквивалентно Linux tr команды:

$tr = array("0" => "a","1" => "b","2" => "c","3" => "d","4" => "e","5" => "f","6" => "g","7" => "h","8" => "i","9" => "j","a" => "k","b" => "l","c" => "m","d" => "n","e" => "o","f" => "p"); 
$haystack = "a5c9a06bfacf5f12cf01ab3f202f6c78" 

echo strtr($haystack, $tr); 
1

Just use strtr

$haystack = "a5c9a06bfacf5f12cf01ab3f202f6c78" ; 
echo strtr($haystack, implode($find), implode($replace)); 

Or preg_replace_callback

$find = array_flip($find); 
echo preg_replace_callback('/[a-f0-9]/', function ($v) use($replace, $find) { 
    return $replace[$find[$v[0]]]; 
}, $haystack); 

Выход

kfmjkaglpkmpfpbcmpabkldpcacpgmhi 
Смежные вопросы