如果您需要进行直接的字符串替换,而不是多次重复结果字符串,您应该使用strtr()
:
strtr($string, array(
'imprint' => 'print',
'print' => 'imprint',
'paper' => 'machine',
));
要替换的单词按字符串长度排序,最具体的在前。
注意:这当然不像正则表达式那样灵活,尤其是在只替换完整的单词时,即只有当它自己存在时/\bword\b/
才会匹配;word
这不是你可以strtr()
和朋友一起做的事情。
使用正则表达式
要preg_replace()
仅对字符串执行一次传递,您需要将替换键组合成一个表达式,即
/imprint|print|paper/
此表达式使用交替,受搜索字符串之间的管道字符影响。要仅匹配整个单词,您需要添加边界匹配,这是一个\b
匹配单词和非单词之间转换的特殊序列。
/\b(?:imprint|print|paper)\b/
这将匹配"imprint"
但不匹配"pimprint"
。
如果您要沿着这条路线走,则需要使用preg_replace_callback()
;来执行替换。对于每个匹配,它都会执行一个自定义函数,您可以在其中确定用什么替换它。您需要为其创建一个替换地图,就像我在之前的strtr()
示例中使用的那样。
$map = array(
'imprint' => 'print',
'print' => 'imprint',
'paper' => 'machine',
);
$replacer = function($match) use ($map) {
// $match[0] holds the found word
return $map[$match[0]];
};
preg_replace_callback('/\b(?:imprint|print|paper)\b/', $string, $replacer);
让它充满活力
我手动创建了正则表达式,但为了使其灵活,您需要根据替换映射动态生成它。为此,我们需要:
- 从替换映射中提取键;
- 转义任何特殊字符;
- 构建最终表达式。
这是构建表达式的方式:
// step 1
$replacement_keys = array_keys($map);
// step 2
$escaped_keys = array_map(function($key) {
return preg_quote($key, '/');
}, $replacement_keys);
// step 3
$pattern = '/\b(?:' . join('|', $escaped_keys) . ')\b/';