正则表达式 preg_replace 在 bbcode 时中断

regex preg_replace breaks when bbcode

我正在结果页面上创建搜索词的突出显示。

这是我现在用的:

$resmessage = preg_replace ( '/' . preg_quote ( $searchword, '/' ) . "/iu", '<span  class="searchword" >' . $searchword . '</span>', $resmessage );

但是当这个词是附件上的标题名称时会破坏布局。

示例文本:

test ok /n[attachment=1]test-2.png[/attachment]

结果:

test ok test-2.png" title="test-2.png" rel="lightbox[imagelink2]">  test-2.png" style="max-height:800px;" alt="" />

所以我想在搜索词之前排除 none 个字符。 正则表达式是什么,我尝试了很多选项。

这应该可以为您完成。 \s 是白色 space(制表符、换行符或 space),+ 表示一个或多个白色 space 字符。

<?php
$resmessage = "test ok /n[attachment=1]test-2.png[/attachment]";
$searchword = 'test';
echo preg_replace ( '/' . preg_quote ( $searchword, '/' ) . "\s+/iu", '<span  class="searchword" >' . $searchword . '</span>', $resmessage);

输出:

<span  class="searchword" >test</span>ok /n[attachment=1]test-2.png[/attachment]

你可以用你想要的任何东西替换它 preg_replace 的第二个参数就是你想要的。 http://php.net/manual/en/function.preg-replace.php

所以

echo preg_replace ( '/' . preg_quote ( $searchword, '/' ) . "\s+/iu", '[b]' . $searchword . '[/b]', $resmessage);

会给你

[b]test[/b]ok /n[attachment=1]test-2.png[/attachment]

您可以使用正则表达式回溯控制动词((*SKIP)(*FAIL) 部分)。

这将允许您匹配任何不在 BBcode 内的字符串(标签之间或标签名称本身):

$searchword = "test";

$resmessage  = "test attachment ok \n[attachment=1]test-2.png[/attachment] test ";
$resmessage .= "[test]test[/test] ok [attachment=1]my-test-2.png[/attachment] test";

$pattern = '/\[.+?\].*?\[\/.+?\](*SKIP)(*FAIL)|' . 
    preg_quote($searchword, '/') . 
    "/iu";

$resmessage = preg_replace(
    $pattern, 
    '<span class="searchword">' . $searchword . '</span>', 
    $resmessage
);

这将 return:

<span class="searchword">test</span> attachment ok 
[attachment=1]test-2.png[/attachment] <span class="searchword">test</span> 
[test]test[/test] ok [attachment=1]my-test-2.png[/attachment] 
<span class="searchword">test</span>