用bb代码替换html标签

时间:2011-04-05 23:03:39

标签: php regex string

如何使用类似BBcode的标签替换某些HTML标签?

例如,将<a ...> ... </a>替换为[url ...] ... [/url] 来自$ var字符串的<code ...> ... </code>[code ...] ... [/code]

4 个答案:

答案 0 :(得分:2)

您可以编写自定义XSLT来转换格式并运行它并XSLT processor以获得所需的输出。

答案 1 :(得分:1)

要转换使用HTML标签的旧文章,我创建了这个非常复杂的脚本。 $ body变量包含文章文本。此过程能够使用特殊标记替换pre和code标记。转换所有其他标记后,脚本将用文本替换上一个标记。 此过程适用于html或bbcode文本。

  // Let's find all code inside the body. The code can be inside <pre></pre>, <code></code>, or [code][/code] if you
  // are using BBCode markup language.
  $pattern = '%(?P<openpre><pre>)(?P<contentpre>[\W\D\w\s]*?)(?P<closepre></pre>)|(?P<opencode><code>)(?P<contentcode>[\W\D\w\s]*?)(?P<closecode></code>)|(?P<openbbcode>\[code=?\w*\])(?P<contentbbcode>[\W\D\w\s]*?)(?P<closebbcode>\[/code\])%i';

  if (preg_match_all($pattern, $body, $snippets)) {

    $pattern = '%<pre>[\W\D\w\s]*?</pre>|<code>[\W\D\w\s]*?</code>|\[code=?\w*\][\W\D\w\s]*?\[/code\]%i';

    // Replaces the code snippet with a special marker to be able to inject the code in place.
    $body = preg_replace($pattern, '___SNIPPET___', $body);
  }


  // Replace links.
  $body = preg_replace_callback('%(?i)<a[^>]+>(.+?)</a>%',

    function ($matches) use ($item) {

      // Extracts the url.
      if (preg_match('/\s*(?i)href\s*=\s*("([^"]*")|\'[^\']*\'|([^\'">\s]+))/', $matches[0], $others) === 1) {
        $href = strtolower(trim($others[1], '"'));

        // Extracts the target.
        if (preg_match('/\s*(?i)target\s*=\s*("([^"]*")|\'[^\']*\'|([^\'">\s]+))/', $matches[0], $others) === 1)
          $target = strtolower(trim($others[1], '"'));
        else
          $target = "_self";
      }
      else
        throw new \RuntimeException(sprintf("Article with idItem = %d have malformed links", $item->idItem));

      return "[url=".$href." t=".$target."]".$matches[1]."[/url]";

    },

    $body
  );


  // Replace images.
  $body = preg_replace_callback('/<img[^>]+>/i',

    function ($matches) use ($item) {

      // Extracts the src.
      if (preg_match('/\s*(?i)src\s*=\s*("([^"]*")|\'[^\']*\'|([^\'">\s]+))/', $matches[0], $others) === 1)
        $src = strtolower(trim($others[1], '"'));
      else
        throw new \RuntimeException(sprintf("Article with idItem = %d have malformed images", $item->idItem));

      return "[img]".$src."[/img]";

    },

    $body
  );


  // Replace other tags.
  $body = preg_replace_callback('%</?[a-z][a-z0-9]*[^<>]*>%i',

    function ($matches) {
      $tag = strtolower($matches[0]);

      switch ($tag) {
        case ($tag == '<strong>' || $tag == '<b>'):
          return '[b]';
          break;

        case ($tag == '</strong>' || $tag == '</b>'):
          return '[/b]';
          break;

        case ($tag == '<em>' || $tag == '<i>'):
          return '[i]';
          break;

        case ($tag == '</em>' || $tag == '</i>'):
          return '[/i]';
          break;

        case '<u>':
          return '[u]';
          break;

        case '</u>':
          return '[/u]';
          break;

        case ($tag == '<strike>' || $tag == '<del>'):
          return '[s]';
          break;

        case ($tag == '</strike>' || $tag == '</del>'):
          return '[/s]';
          break;

        case '<ul>':
          return '[list]';
          break;

        case '</ul>':
          return '[/list]';
          break;

        case '<ol>':
          return '[list=1]';
          break;

        case '</ol>':
          return '[/list]';
          break;

        case '<li>':
          return '[*]';
          break;

        case '</li>':
          return '';
          break;

        case '<center>':
          return '[center]';
          break;

        case '</center>':
          return '[/center]';
          break;

        default:
          return $tag;
      }
    },

    $body
  );


  // Now we strip the remaining HTML tags.
  $body = strip_tags($body);


  // Finally we can restore the snippets, converting the HTML tags to BBCode tags.
  $snippetsCount = count($snippets[0]);

  for ($i = 0; $i < $snippetsCount; $i++) {
    // We try to determine which tags the code is inside: <pre></pre>, <code></code>, [code][/code]
    if (!empty($snippets['openpre'][$i]))
      $snippet = "[code]".PHP_EOL.trim($snippets['contentpre'][$i]).PHP_EOL."[/code]";
    elseif (!empty($snippets['opencode'][$i]))
      $snippet = "[code]".PHP_EOL.trim($snippets['contentcode'][$i]).PHP_EOL."[/code]";
    else
      $snippet = $snippets['openbbcode'][$i].PHP_EOL.trim($snippets['contentbbcode'][$i]).PHP_EOL.$snippets['closebbcode'][$i];

    $body = preg_replace('/___SNIPPET___/', PHP_EOL.trim($snippet).PHP_EOL, $body, 1);
  }

  //echo $body;

答案 2 :(得分:0)

反向HTML到BBCODE转换并不困难。图书馆存在,我相信我们有一个重复的答案。但我也不善于搜索。

基本上你可以这样使用preg_replace

 // for 1:1 translations
 $text = preg_replace('#<(/?)(b|i|code|pre)>#', '[$1$2]', $text);

 // complex tags
 $text = preg_replace('#<a href="([^"]+)">([^<]+)</a>#',
             "[url=$1]$2[/url]", $text);

但如果您的输入HTML与预期不完全匹配,则第二种情况将会失败。如果您尝试转换导出的Word文件,这种简单的方法将失败。另外,[img]和东西需要更多特殊情况。

答案 3 :(得分:0)

不是一项微不足道的任务。我一会儿看了这个,我遇到的最好的代码就是这个:cbparser