那么这里会发生什么?
$text = " a b c ";
$text = strtr($text, array(" a " => " b ", " b " => " a ", " c " => " d "));
首先你要知道:
- 最长的键将首先被替换
- 更换后不再搜索此密钥
所以这里所有的键都具有相同的长度,这意味着它将替换第一个key => value
元素,然后是第二个元素,依此类推。
所以首先" 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);
?>