问题:我需要更换' m'因为' n'所有的单词都是在' m'上完成的,而不是' m'它自我。
示例文字:Bombom有一个m。
预期回报: Bombon有一个m。
当前的PHP代码: $txt = preg_replace('/(m)(?=\\s|$)/i', 'n', $txt);
但它返回: Bombon有一个n。
加分:我想要" Word"为[a-zA-ZÀ-ÿ]
,因此3m
不应替换为3n
。
Bonus two (针对其他类似问题):告诉我如何替换Use Q for Iraq and Qatar
Use Q for Irak and katar
(替换所有出现的情况除外)
答案 0 :(得分:0)
当你正在寻找只出现在一个单词末尾的m
时,即它后面应该是一个单词边界,但前面有一个字母。您可以像这样使用negative lookbehind
。
正则表达式:/(?<=[A-Za-z])m\b/
<强>解释强>:
m\b
匹配m
后跟字边界。因此Bombom
和m
应匹配。但我们只需要Bombom
。因此,请使用negative lookbehind
。
(?<=[A-Za-z])
在匹配m
之前查找一封信。
然后将其替换为n
。
它与3m
不匹配,因为m
前面有数字。
的 Regex101 Demo 强>
答案 1 :(得分:0)
没有正则表达式,但这样做..
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);
}
答案 2 :(得分:0)
您可以使用.
来匹配非字母/数字,并将其再次包含在替换字符串中:
[^\w]
输出:
Bombon有一个m,而不是3m。
正则表达式将获取前面的字母,其必须是字母($input = "Bombom has an m, not 3m.";
$output = preg_replace("/([a-zÀ-ÿ])m($|[^\w])/i", "$1n$2", $input);
echo $output . "<br>";
),作为组1,以及下面的非字母/数字a-zÀ-ÿ
(或字符串{{1的结尾) }})作为第2组,并在替换字符串中分别使用[^\w]
和$
进行恢复。
对于Q的情况,您可以使用:
$1
输出:
为伊拉克和卡塔尔使用Q
这里使用OR运算($2
)扩展原理。由于现在有4个捕获组,所有四个都需要在替换字符串中恢复,即使其中只有两个将被实现。另外两个将是空字符串,因此如果它们也存在则不会破坏结果。
正则表达式末尾的$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>";
选项可确保|
和i
匹配(不区分大小写)。