それで、ここで何が起こりますか?
$text = " a b c ";
$text = strtr($text, array(" a " => " b ", " b " => " a ", " c " => " d "));
まず、次のことを知っておく必要があります。
- 最も長いキーが最初に置き換えられます
- 置き換えられた後、このキーを検索しなくなりました
したがって、ここではすべてのキーの長さが同じです。つまり、最初のkey => value
要素が置き換えられ、次に 2 番目の要素が置き換えられます。
したがって、最初" a " => " b "
に置き換えられ、開始文字列が変更されます。
a b c
↑↑↑ Match
これに:
b b c
↑↑↑ Replacement
値を置き換えた後は、もう検索しないと言ったことを覚えていますか? 丁度!が検索されます" b " => " a "
が、文字列のこの部分のみが検索されます。
紀元前_
b の前に検索するスペースがないため、検索されません。そのため、期待した出力が得られません。そしてc
、その前にスペースがあるので、再び見つかります。
したがって、ここでのコードの問題は、次のキーの検索に置き換えられた値が含まれていないことです。が文字列に含まれていても[space]b[space]
、最初のスペースは key の置換された値からのもの[space]a[space]
であり、次の検索には含まれないため、見つかりません。
編集:
あなたの更新された質問から、単語が他の単語の一部になるのを防ぐためにこれを行ったようです。これを解決するには、ルックアップ配列を作成preg_replace_callback()
し、単語境界で使用して、その一部だけではなく完全な単語のみに一致させます。
<?php
$text = " apple bacon cats ";
$replacement = ["apple" => "bacon", "bacon" => "apple", "cats" => "dogs"];
$search = array_map(function($v){
return preg_quote($v, "/");
}, array_keys($replacement));
echo $text = preg_replace_callback("/\b(" . implode("|", $search) . ")\b/", function($m)use($replacement){
return $replacement[$m[1]];
}, $text);
?>