Regex/preg_replace删除[font#ABCDEF]$text[/font] BBcode之间的额外换行符


Regex/preg_replace to remove extra line breaks between [font#ABCDEF]$text[/font] BBcode

有一个用户可以发布消息的博客。他们可以使用BB代码字体。问题-当前脚本不删除多个换行时,文本张贴在这个字体BB代码(它工作正确的明文)。

所以我的想法是添加一个preg_replace函数,以便它从字体BB代码内发布的文本中删除额外的行。字体BB代码以[font#ABCDEF]开头,以[/font]结尾。

例如:

[font#FF0000]

This text is in red.
Hello world. How are you?



Good, thanks.

[/font]

在preg_replace之后应该最多有2个换行符(例如:如果有人增加了6个换行,他们应该减少到2个;如果有人添加了1或2个换行符,他们应该在输入时留下。1或2),等等

这是我目前的尝试,但它似乎没有工作,即使它应该是接近正确的解决方案,我希望:

$text=preg_replace("#('[font[^']]*?'])['r'n ]+#i", "''1", $text);
$text=preg_replace("#['r'n ]+('[/font'])#i", "''1", $text);
$text=preg_replace("#('[/font'])['r'n]{2,}#i","''1'n", $text);

(理想情况下,最好不要在开始[font#ABCDEF]标记之后和结束[/font]标记之前留下任何换行符,因为那里根本不需要换行符。

您可以使用这种使用'G锚的模式。该锚匹配上次匹配之后的位置,因此获得连续的结果非常有用:

$pattern = '~
(?:
    'G(?!'A)      # position after the last match
  |              # or
    '[font[^]]*]  # start tag
     (?: 'K 'R+ (*ACCEPT) )? # if leading newlines,
                             # (*ACCEPT) forces the pattern to succeed immediatly
)
(?> [^'r'n[]* 'K 'R )*? # lines until:
# ('K removes all on the left from the match result)
(?:
    'R+(?='[/font]) # the end 
  |                # or
    'R 'K 'R+       # more than two newlines
)
~xi';
$txt = preg_replace($pattern, '', $txt);

preg_replace_callback还有另一种方法:模式查找字体标记之间的内容,回调函数删除不需要的换行符:

$txt = preg_replace_callback('~'[font[^]]*]'K[^[]+(?='[/font])~i', function ($m) {
    return preg_replace('~'R'R'K'R+~', '', trim($m[0], "'r'n"));
}, $txt);

这将把3个或更多的换行符转换为2个:

$text=preg_replace("/('r|'n){3,}/", "'n'n", $text);

这将直接删除[font]标签后面的所有空白:

$text=preg_replace("/('[font#.{6}'])('s)*/", "$1", $text);

试试:http://sandbox.onlinephpfunctions.com/code/435951e8dd1039ce8da41d64c501f4bf46c79cc6