问题:我需要在所有以"m"结尾的单词中将"m"替换为"n",而不是"m"本身。
示例文本:炸弹有一个 m。
预期回报:邦邦有一个m。
当前 PHP 代码:$txt = preg_replace('/(m)(?=''s|$)/i', 'n', $txt);
但它返回:Bombon有一个n。
奖励一:我希望"Word"[a-zA-ZÀ-ÿ]
,所以,3m
不应该被替换为3n
。
奖励二(对于另一个类似的问题(:告诉我如何用Use Q for Iraq and Qatar
替换Use Q for Irak and katar
(替换所有出现的,除非单独出现(。
当您正在寻找仅出现在单词末尾的m
时,即它后面应该跟着一个单词边界,但前面有一个字母。你可以像这样使用negative lookbehind
。
正则表达式:/(?<=[A-Za-z])m'b/
解释:
m'b
匹配m
后跟单词边界。所以Bombom
和m
应该匹配。但我们只需要Bombom
.所以使用negative lookbehind
.
(?<=[A-Za-z])
在匹配m
之前寻找一个字母。
然后将其替换为n
.
它与3m
不匹配,因为m
前面有一个数字。
正则表达式 101 演示
没有正则表达式,但这样可以做到。
function replaceLastLetter($search, $replace, $subject){
$words = explode(" ", $subject);
for($i=0; $i<count($words); $i++){
$last = substr($words[$i], -1);
if($last == $search && strlen($words[$i])>1){
$words[$i] = substr($words[$i], 0, strlen($words[$i])-1).$replace;
}
}
return implode(" ", $words);
}
https://3v4l.org/lJ4WN
[^'w]
来匹配非字母/数字,并将它们再次包含在替换字符串中:
$input = "Bombom has an m, not 3m.";
$output = preg_replace("/([a-zÀ-ÿ])m($|[^'w])/i", "$1n$2", $input);
echo $output . "<br>";
输出:
炸弹有一个m,而不是3m。
正则表达式将获取前面的字母(必须是字母 ( a-zÀ-ÿ
(,作为组 1,后面的非字母/数字[^'w]
(或字符串 $
的末尾(作为组 2,并在替换字符串中分别使用 $1
和 $2
恢复这些。
对于 Q 的情况,您可以使用以下内容:
$input = "Use Q for Iraq and Qatar";
$output = preg_replace("/(?:([a-zÀ-ÿ])q($|[^'w])|(^|[^'w])q($|[a-zÀ-ÿ]))/i",
"$1$3k$2$4", $input);
echo $output . "<br>";
输出:
使用 Q 表示伊拉克和卡塔尔
这里原理用OR运算(|
(扩展。由于现在有 4 个捕获组,因此需要在替换字符串中还原所有四个捕获组,即使其中只有两个将实现。另外两个将是空字符串,因此如果它们也存在,它不会破坏结果。
正则表达式末尾的i
选项可确保q
和Q
匹配(不区分大小写(。