使用str_replace或其他函数替换标签。

3

是否有一种方法可以仅在同时存在开标签和闭标签时替换标签,例如:

//search to replace
$text = '[b]this will be bold[/b] but this will be not.';
$search = array('[b]long string[/b]');
//replace with
$replace = array('<b>long string</b>');
echo str_replace($search, $replace, $text);

期望结果:

这将会是粗体 但这不会是。

我不确定如何正确设置它,任何帮助都将感激不尽。


你需要替换一个模式而不是一个特定的字符串。正则表达式可以帮助你实现这个功能。 - Marty
2
为什么不允许使用(一些)HTML标签?或者考虑使用markdown(有很多库可供使用)? - ItalyPaleAle
对于Markdown,我给出一个赞。Michel Fortin在这里有一个相当不错的Markdown解析器:http://michelf.ca/projects/php-markdown/ - Benjamin Nolan
4个回答

3
听起来你想要实现一个BBCodes系统,你需要使用正则表达式来完成。
这里有一篇非常好的文章:http://thesinkfiles.hubpages.com/hub/Regex-for-BBCode-in-PHP,其中详细解释了如何使用正则表达式,并解释了各种正则表达式部分的含义,以便您稍后编写自己的添加内容。
然而,将你上面的示例转换为代码如下:
$text = '[b]this will be bold[/b] but this will be not.';
$ret = $text; // So we don't overwrite the original variable.
$ret = preg_replace('#\[b\](.+)\[\/b\]#iUs', '<b>$1</b>', $ret);

1
这个完美地实现了我的正则表达式在一个数组上,谢谢 :) - user2444411

2
这样做就可以实现这个功能:
//search to replace
$text = '[b]this will be bold[/b] but this will be not.';
$search = array('~\[([^]]+)\]([^][]*)\[/\1\]~');
//replace with
$replace = array('<$1>$2</$1>');
echo preg_replace($search, $replace, $text);

输出:

<b>this will be bold</b> but this will be not.

这里有一个PHP演示

正则表达式演示和解释:

\[([^]]+)\]([^][]*)\[/\1\]

正则表达式可视化

Debuggex演示

注意:这是非常简化的,忽略了一些严重的安全问题。实际上,你必须考虑像禁止<script><iframe>和其他可能导致跨站点脚本注入的标签。

像这样的东西,使用解析器比正则表达式更可靠。

如果你真的想使用正则表达式:用一个被允许的标签组替换([^]]+)。例如:

\[(b|em|i|strong)\]([^][]*)\[/\1\]  // allows only b, em, i, and strong

这很可能非常不安全,容易受到 XSS 攻击。 - ItalyPaleAle
同意,你将会实现更多的异常而不是规则。 :/ - Benjamin Nolan
是的,我明白你的意思了。回答我的问题,但我想要一个自由地将 [this] [/this] 替换为不一定与标签相同的内容的方法。 - user2444411
啊,这种情况下,您可能需要使用替换数组。例如,如果您想将[b]...[/b]替换为<foo>...</foo>,并将[i]...[/i]替换为<bar>...</bar>,那么就需要使用某种形式的数组和/或回调函数。 - elixenide
哎呀...我本来以为你会的!:s - Benjamin Nolan
显示剩余4条评论

1

我可以为您编写高级的BBcode解析函数。

您可以在$tags = 'b|url';中添加任何BBcode标签。

例如:

$tags = 'b|url|i|e|img';

此外,它支持带有内部标签的BBCode,例如[url=http://www.website.com]blaa[/url]

这是完整的代码

function parseBBCODE($text)
{
    //bbcodes tags
    $tags = 'b|url';


    //loop tags sub tags too
    while (preg_match_all('#\[('.$tags.')=?(.*?)\](.+?)\[/\1\]#is',$text, $matches))
    foreach ($matches[0] as $key => $match)
    {
       //extract tag info
       list($tag, $param, $innertext) = array($matches[1][$key], $matches[2][$key], $matches[3][$key]);

        //match tags and replace them
        switch ($tag)
        {
          //Bold
          case 'b':
             $replacement    = '<b>'.$innertext.'</b>';
          break;
          //link url
          case 'url':
            $replacement = '<a target="_blank" href="'.($param ? $param : $innertext).'">'.$matches[3][$key].'</a>';
          break;
          default :
           $replacement = "";
        }

      $text = str_replace($match, $replacement,$text);
      unset($match,$replacement,$param);
    }

   return $text;
}


 $search = '[b]long string [/b]  [url]http://www.google.com[/url]   [url=http://www.google.com]url with tag[/url]';

 echo parseBBCODE($search);

1
您可以使用正则表达式来实现这个功能:
$text = '[b]this will be bold[/b] but this will be not.';
$text = preg_replace('/\[([a-z]+)\](.*?)\[\/\1\]/', '<\1>\2</\1>', $text);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接