2010-11-17 2 views
0

Я сделал ничего программного обеспечение заметки в PHP, так что я могу хранить и организовывать свои заметки и желаю для приятного простого формата, чтобы написать их.Рекомендация для реализации простых регулярных выражений (для BBcode/Geshi синтаксических)

Я имел сделал это в Markdown, но обнаружил, что это немного запутывает и не было простого подсветки синтаксиса, поэтому я сделал bbcode раньше и хотел реализовать это.

Теперь GeSHi, который я действительно хочу реализовать (синтаксис фломастер), он требует самого простого кода:

$geshi = new GeSHi($sourcecode, $language); 
$geshi->parse_code(); 

Теперь это легкая часть, но то, что я хочу сделать, это позволить мой bbcode, чтобы позвонить ему.

Мой текущий регулярное выражение, чтобы соответствовать составленную [синтаксис = CPP] [/ синтаксис] BBCode заключается в следующем:

preg_replace('#\[syntax=(.*?)\](.*?)\[/syntax\]#si' , 'geshi(\\2,\\1)????', text); 

Вы заметите, что я захватить язык и содержание, как на земле, я бы подключить его к GeSHi-коду?

preg_replace кажется просто быть в состоянии заменить его в строку не «выражение», я не знаю, как использовать эти две строки кода для GeSHi там с захваченных данных ..

Я действительно Я в восторге от этого проекта и хочу его преодолеть.

ответ

2

Я написал этот класс некоторое время назад, причина для класс должен был легко настраивать/разбор. Может быть, немного переборщил, но работает хорошо, и мне было нужно, чтобы он был излишним для моего заявления. Использование довольно прост:

$geshiH = new Geshi_Helper(); 
$text = $geshiH->geshi($text); // this assumes that the text should be parsed (ie inline syntaxes) 

---- ИЛИ ----

$geshiH = new Geshi_Helper(); 
$text = $geshiH->geshi($text, $lang); // assumes that you have the language, good for a snippets deal 

я должен был сделать некоторые не прерывая других пользовательских элементов, которые я имел, но в ожидании синтаксических ошибок из рубить он должен работать. Не стесняйтесь использовать его.

<?php 

require_once 'Geshi/geshi.php'; 

class Geshi_Helper 
{ 
    /** 
    * @var array Array of matches from the code block. 
    */ 
    private $_codeMatches = array(); 

    private $_token = ""; 

    private $_count = 1; 

    public function __construct() 
    { 
     /* Generate a unique hash token for replacement) */ 
     $this->_token = md5(time() . rand(9999,9999999)); 
    } 

    /** 
    * Performs syntax highlights using geshi library to the content. 
    * 
    * @param string $content - The context to parse 
    * @return string Syntax Highlighted content 
    */ 
    public function geshi($content, $lang=null) 
    { 
     if (!is_null($lang)) { 
      /* Given the returned results 0 is not set, adding the "" should make this compatible */ 
      $content = $this->_highlightSyntax(array("", strtolower($lang), $content)); 
     }else { 
      /* Need to replace this prior to the code replace for nobbc */ 
      $content = preg_replace('~\[nobbc\](.+?)\[/nobbc\]~ie', '\'[nobbc]\' . strtr(\'$1\', array(\'[\' => \'&#91;\', \']\' => \'&#93;\', \':\' => \'&#58;\', \'@\' => \'&#64;\')) . \'[/nobbc]\'', $content); 

      /* For multiple content we have to handle the br's, hence the replacement filters */ 
      $content = $this->_preFilter($content); 

      /* Reverse the nobbc markup */ 
      $content = preg_replace('~\[nobbc\](.+?)\[/nobbc\]~ie', 'strtr(\'$1\', array(\'&amp;#91;\' => \'[\', \'&amp;#93;\' => \']\', \'&amp;#58;\' => \':\', \'&amp;#64;\' => \'@\'))', $content); 

      $content = $this->_postFilter($content); 
     } 

     return $content; 
    } 

    /** 
    * Performs syntax highlights using geshi library to the content. 
    * If it is unknown the number of blocks, use highlightContent 
    * instead. 
    * 
    * @param string $content - The code block to parse 
    * @param string $language - The language to highlight with 
    * @return string Syntax Highlighted content 
    * @todo Add any extra/customization styling here. 
    */ 
    private function _highlightSyntax($contentArray) 
    { 
     $codeCount = $contentArray[1]; 

     /* If the count is 2 we are working with the filter */ 
     if (count($contentArray) == 2) { 
      $contentArray = $this->_codeMatches[$contentArray[1]]; 
     } 

     /* for default [syntax] */ 
     if ($contentArray[1] == "") 
      $contentArray[1] = "php"; 

     /* Grab the language */ 
     $language = (isset($contentArray[1]))?$contentArray[1]:'text'; 

     /* Remove leading spaces to avoid problems */ 
     $content = ltrim($contentArray[2]); 

     /* Parse the code to be highlighted */ 
     $geshi = new GeSHi($content, strtolower($language)); 
     return $geshi->parse_code(); 
    } 

    /** 
    * Substitute the code blocks for formatting to be done without 
    * messing up the code. 
    * 
    * @param array $match - Referenced array of items to substitute 
    * @return string Substituted content 
    */ 
    private function _substitute(&$match) 
    { 
     $index = sprintf("%02d", $this->_count++); 
     $this->_codeMatches[$index] = $match; 
     return "----" . $this->_token . $index . "----"; 
    } 

    /** 
    * Removes the code from the rest of the content to apply other filters. 
    * 
    * @param string $content - The content to filter out the code lines 
    * @return string Content with code removed. 
    */ 
    private function _preFilter($content) 
    { 
     return preg_replace_callback("#\s*\[syntax=(.*?)\](.*?)\[/syntax\]\s*#siU", array($this, "_substitute"), $content); 
    } 

    /** 
    * Replaces the code after the filters have been ran. 
    * 
    * @param string $content - The content to replace the code lines 
    * @return string Content with code re-applied. 
    */ 
    private function _postFilter($content) 
    { 
     /* using dashes to prevent the old filtered tag being escaped */ 
     return preg_replace_callback("/----\s*" . $this->_token . "(\d{2})\s*----/si", array($this, "_highlightSyntax"), $content); 
    } 
} 
?> 
+0

Хотел бы я, чтобы я мог +10, я обязательно подберу и использую этот класс. Спасибо. – John

+0

Одно из регулярных выражений мне пришлось заменить разделители от '/' до '#', и он отлично работает :) – John

+0

Какой? Я исправлю это, чтобы другие не путались. –

1

Использования preg_match:

$match = preg_match('#\[syntax=(.*?)\](.*?)\[/syntax\]#si', $text); 
$geshi = new GeSHi($match[2], $match[1]); 
2

Она смотрит на меня, как вы уже получили регулярки права. Ваша задача заключается в вызове, так что я предлагаю сделать функцию обертки:

function geshi($src, $l) { 
    $geshi = new GeSHi($sourcecode, $language); 
    $geshi->parse_code(); 
    return $geshi->how_do_I_get_the_results(); 
} 

Теперь это, как правило, хватает, но исходный код может содержать один или сам dobule кавычки. Поэтому вы не можете написать preg_replace(".../e", "geshi('$2','$1')", ...), как вам нужно. (Обратите внимание, что «$ 1» и «$ 2» нуждаются в кавычках, потому что preg_replace просто заменяет заполнители $ 1, $ 2, но это должен быть действительный встроенный код php).

Вот почему вам нужно использовать preg_replace_callback, чтобы избежать проблем с заменой кода замены e-кода. Так, например:

preg_replace_callback('#\[syntax=(.*?)\](.*?)\[/syntax\]#si' , 'geshi_replace', $text); 

И я хотел бы сделать вторую оболочку, но вы можете комбинировать его с оригинальным кодом:

function geshi_replace($uu) { 
    return geshi($uu[2], $uu[1]); 
} 
+0

Это отвечает на мою оригинальную проблему, спасибо! Я писал это очень поздно, не мог найти никакого решения, это имеет смысл: P – John

Смежные вопросы