jes*_*ica 0 php regex replace strtr preg-replace
我正在尝试用strtr同时替换字符串,但我遇到了一个问题.如果同时更换的字母与另一个同时被替换的字母相邻,则不会替换第一个字母后面的字母.我该怎么做才能解决这个问题?谢谢.
$text = " no bacon cats nobody ";
$text = strtr($text, array(" no " => " bacon ", " bacon " => " no ", " cats " => " dogs "));
echo $text;
Run Code Online (Sandbox Code Playgroud)
预期成绩
bacon no dogs nobody
Run Code Online (Sandbox Code Playgroud)
实际结果
bacon bacon dogs nobody
Run Code Online (Sandbox Code Playgroud)
PS:我必须确保这些词不是另一个词的一部分.这就是为什么白色空间在那里.例如,单词"no"是"nobody"的一部分,如果你在字符串中替换了所有"no",它也会替换像"nobody"这样的单词;
那么这里发生了什么?
$text = " a b c ";
$text = strtr($text, array(" a " => " b ", " b " => " a ", " c " => " d "));
Run Code Online (Sandbox Code Playgroud)
首先你必须知道:
所以这里所有键都具有相同的长度,意味着它将替换第一个key => value元素,然后是第二个元素,依此类推.
所以首先" a " => " b "将被替换,这将改变你的起始字符串:
a b c
??? Match
Run Code Online (Sandbox Code Playgroud)
对此:
b b c
??? Replacement
Run Code Online (Sandbox Code Playgroud)
还记得我们怎么说,在替换它之后它不再搜索它了吗?究竟!现在它搜索" b " => " a ",但只搜索字符串的这一部分:
ab c
所以它找不到它,因为b前面没有空间可以搜索.这就是为什么你没有得到预期的输出.并且c会再次被发现,因为它前面有一个空间.
因此,代码中的问题是,在搜索下一个键时不包含替换值.即使[space]b[space]在你的字符串中,它也找不到它,因为第一个空格来自键的替换值[space]a[space],它不会包含在下一个搜索中.
编辑:
从您更新的问题来看,您似乎已经这样做,试图阻止单词成为其他单词的一部分.要解决这个问题,只需创建一个查找数组并使用preg_replace_callback()单词boundarys来匹配只有完整的单词而不仅仅是它的一部分,例如
<?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);
?>
Run Code Online (Sandbox Code Playgroud)