我从PHP中的preg_replace开始,我想知道如何只将第一个匹配的数组键替换为指定的数组值,因为我将preg_replace的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;
?>
我希望它在输出中显示:
嘿,太糟糕了
(更改一个后缀,更改一个单词并停止)
不是这样的:
嘿,太棒了
(两个后缀更改,两个词更改并返回原始词和后缀...)
也许我可以简化这段代码?我也无法更改数组键和值的顺序,因为很快就会有更多的后缀和单个单词更改。我是php编码的新手,感谢您的帮助;>
答案 0 :(得分:0)
您可以在用于创建动态正则表达式模式的关联数组键中使用纯文本,并使用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
是一个单词边界,它是一种无消耗模式,可确保没有字母,数字或{{ 1}}。
_
解析一次字符串,当匹配发生时,它将与preg_replace_callback
数组(function($m)
)一起传递给匿名函数($words
)。如果use ($words)
数组包含找到的键($words
),则返回对应的值(isset($words[$m[0]])
),否则返回找到的匹配项($words[$m[0]]
)。