preg_replace 数组中的单词
preg_replace with a word in an array
我正在尝试在名为 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
之类的内容,它会起作用,然后将所有问候语替换为 "as"。
我使用的方法是否可行?
如果你像下面这样保持它就会起作用:
$a = preg_replace("/\b".$word."\b/i", "as",$this->code);
之前是pattern,是双引号字符串,所以变量会被替换,问题不大
问题是你用一个循环来改变几个词,然后把结果存入$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);
此技术的唯一限制是区分大小写。
我正在尝试在名为 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
之类的内容,它会起作用,然后将所有问候语替换为 "as"。
我使用的方法是否可行?
如果你像下面这样保持它就会起作用:
$a = preg_replace("/\b".$word."\b/i", "as",$this->code);
之前是pattern,是双引号字符串,所以变量会被替换,问题不大
问题是你用一个循环来改变几个词,然后把结果存入$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);
此技术的唯一限制是区分大小写。