PHP: preg_replace 仅匹配数组中的第一个字符串

PHP: preg_replace only first matching string in array

我从 preg_replace 开始,在 PHP 中,我想知道如何只用指定的数组值替换第一个匹配的数组键,因为我设置了 preg_replace number of changes 参数到“1”,而且它改变了不止一次。我还将我的字符串拆分为单个单词,我正在一个一个地检查它们:

<?php
  $internal_message = 'Hey, this is awesome!';

  $words = array(
     '/wesome(\W|$)/' => 'wful',
     '/wful(\W|$)/' => 'wesome',
     '/^this(\W|$)/' => 'that',
     '/^that(\W|$)/' => 'this'
  );

  $splitted_message = preg_split("/[\s]+/", $internal_message);
  $words_num = count($splitted_message);

  for($i=0; $i<$words_num; $i++) {
     $splitted_message[$i] = preg_replace(array_keys($words), array_values($words), $splitted_message[$i], 1);
  }

  $message = implode(" ", $splitted_message);
  echo $message;
?>

我希望输出:

Hey, that is awful

(一字尾变一字变停)

不是这个:

Hey, this is awesome

(两个后缀更改,两个单词更改并返回原始单词和后缀...)

也许我可以简化这段代码?我也无法更改数组键和值的顺序,因为很快就会有更多的后缀和单个单词需要更改。我是 php 编码方面的新手,非常感谢您的帮助 ;>

您可以在将用于创建动态正则表达式模式的关联数组键中使用纯文本,并使用 preg_replace_callback 一次性将找到的值替换为替换项。

$internal_message = 'Hey, this is awesome!';

$words = array(
    'wesome' => 'wful',
    'wful' => 'wesome',
    'this' => 'that',
    'that' => 'this'
);
$rx = '~(?:' . implode("|", array_keys($words)) . ')\b~';
echo "$rx\n";
$message = preg_replace_callback($rx, function($m) use ($words) {
    return isset($words[$m[0]]) ? $words[$m[0]] : $m[0];
}, $internal_message);
echo $message;
// => Hey, that is awful!

参见PHP demo

正则表达式是

~(?:wesome|wful|this|that)\b~

(?:wesome|wful|this|that) 是一个非捕获组,匹配里面的任何值, \b 是一个词边界,一个非消耗模式,确保没有字母,数字或_后缀。

preg_replace_callback对字符串进行一次解析,当匹配到时,连同$words数组(use ($words)) 并且如果 $words 数组包含找到的键 (isset($words[$m[0]])) 则返回相应的值 ($words[$m[0]]) 否则返回找到的匹配 ($m[0]).