转换此 preg_replace 以匹配带有加号的单词

问题描述 投票:0回答:1

在 PHP 中,我需要突出显示字符串中的多个给定单词,例如将找到的匹配项包装在

<em>
标签内。 但如果我有一个以
+
结尾的单词,我就做不到。

我理解下面的问题是 plus 不是一个单词,并且破坏了

\b
标志单词匹配。但是我怎样才能写这个,以便它匹配并包装所有给定的单词,即使给定的单词以
+
结尾?

$my_text = 'test c+ and javascript etc but NOT javascripter';

$words_to_highlight = array('javascript', 'c+');


foreach($words_to_highlight as $word){
    
    $search_pattern = str_replace('+', '\\+', $word);
    
    // this doesn't match replacement
    echo "\n".preg_replace("/\b(".$search_pattern.")\b/i", '<em>$1</em>', $my_text);
    
    // works if I remove the \b flag, but I don't want to match "javascript" inside "javascripter"
    echo "\n".preg_replace("/(".$search_pattern.")/i", '<em>$1</em>', $my_text);
    
}

输出是:

test c+ and <em>javascript</em> etc but NOT javascripter
test c+ and <em>javascript</em> etc but NOT <em>javascript</em>er

test c+ and javascript etc but NOT javascripter
test <em>c+</em> and javascript etc but NOT javascripter

我想要的结果是:

test <em>c+</em> and <em>javascript</em> etc but NOT javascripter
php regex pattern-matching preg-replace regexp-replace
1个回答
0
投票

您可以使用环视形式的空白边界,而不是使用单词边界,断言左侧和右侧不是非空白字符。

对于正则表达式语法中的转义字符,您可以使用 preg_quote

为了一次性替换,您可以使用列出所有替代方案的非捕获组动态创建正则表达式。

最终的图案如下所示:

(?<!\S)(?:javascript|c\+)(?!\S)

查看 regex 演示PHP 演示中的匹配。

例如:

$my_text = 'test c+ and javascript etc but NOT javascripter';
$words_to_highlight = array('javascript', 'c+');

$pattern = sprintf(
    "/(?<!\S)(?:%s)(?!\S)/i",
    implode('|', array_map("preg_quote", $words_to_highlight))
);

echo preg_replace($pattern, '<em>$0</em>', $my_text);

输出

test <em>c+</em> and <em>javascript</em> etc but NOT javascripter
© www.soinside.com 2019 - 2024. All rights reserved.