2011-04-05 126 views
0

如何用BBcode標籤替換某些HTML標籤?用bb代碼替換html標籤

例如與[url ...] ... [/url]<code ...> ... </code>[code ...] ... [/code]從$ var的字符串替換<a ...> ... </a>

+0

幾乎每個元素都需要單獨的正則表達式。 – 2011-04-05 23:16:40

+0

去掉所有原生html不要替換它,讓你的用戶添加指定的BBcode,然後你可以替換爲html對應 – 2011-04-05 23:43:05

回答

0

反向的HTML BB代碼轉換都不難。圖書館是爲此而存在的,我確定我們有一個重複的答案。但我也不好尋找。

基本上你可以使用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]和其他東西的更多特殊情況。

+0

大多數情況下會失敗,但它回答了這個問題。 – 2011-04-05 23:22:53

+0

我想這是關於重新導入。所以如果有1:1的相關性,它可能會有。但是,要想爲此製作一個現成的且實際可行的腳本,這是非常困難的。 – mario 2011-04-05 23:25:19

+0

毫無疑問''等等,但錨點,圖像等並不是微不足道的,除非HTML沒有嚴格定義爲例如''。我需要類似這樣的東西,但由於蹩腳的所見即所得編輯器(很多垃圾)而無法構建正則表達式。 – 2011-04-05 23:35:39

2

您可以編寫一個自定義的XSLT來轉換格式並運行它並通過XSLT processor獲得所需的輸出。

0

不是一項簡單的任務。我回頭看了一會兒,我碰到的最好的代碼是這一個:cbparser

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;