preg_replace,在数组中包含单词

时间:2015-02-20 16:35:31

标签: php preg-replace

我正在尝试使用名为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;。

这种方法是否可能使用?

2 个答案:

答案 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);