我正在尝试使用名为keywords
的数组中的某些单词,这些单词将被用于在字符串中替换为" as"。
for($i = 0; $i<sizeof($this->keywords[$this->lang]); $i++)
{
$word = $this->keywords[$this->lang][$i];
$a = preg_replace("/\b$word\b/i", "as",$this->code);
}
如果我用$word
之类的东西替换变量/\bhello\b/i
,那么它将用&#34;替换所有你好的单词作为&#34;。
这种方法是否可能使用?
答案 0 :(得分:1)
在成为模式之前,它是一个双引号字符串,因此变量将被替换,这不是问题。
问题是您使用循环来更改多个单词,并将结果存储在$a
中:
$this->code
中第一个单词的所有出现都被替换,新的字符串存储在$a
中。$a
作为第三个参数来替换下一个单词,但始终是原始字符串$this->code
结果:for循环$a
包含原始字符串,但只有最后一个单词的出现被as
替换。
当您想用相同的字符串替换多个单词时,一种方法是构建一个替换:word1|word2|word3...
。可以使用implode
:
$alternation = implode('|', $this->keywords[$this->lang]);
$pattern = '~\b(?:' . $alternation . ')\b~i';
$result = preg_replace($pattern, 'as', $this->code);
因此,当你这样做时,字符串只被解析一次,所有的单词都被一次性替换。
如果你有很多单词和很长的字符串:
测试长时间的交替会产生很大的成本。即使模式以\b
开头,大大减少了匹配的可能位置,您的模式也很难成功,而且更难以失败。
只有在这种特殊情况下,您才能使用另一种方式:
首先定义一个占位符(一个不能在你的字符串中的字符或一个小字符串,比如§
),它将插入到字边界的每个位置。
$temp = preg_replace('~\b~', '§', $this->code);
然后您更改所有关键字,例如§word1§
,§word2§
...并构建一个关联数组,其中所有值都是替换字符串:
$trans = [];
foreach ($this->keywords[$this->lang] as $word) {
$trans['§' . $word . '§'] = 'as';
}
完成后,添加一个空字符串,并将占位符作为键。您现在可以使用快速strtr
功能执行替换:
$trans['§'] = '';
$result = strtr($temp, $trans);
这项技术的唯一限制是它区分大小写。
答案 1 :(得分:0)
如果你像下面那样保持它会起作用:
$ a = preg_replace(“/ \ b”。$ word。“\ b / i”,“as”,$ this-&gt; code);