Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: paser bbCode
Forum PHP.pl > Forum > PHP
Krzychur
Witam!
Mam nadzieję, że dobre forum wybrałem. Poniższy kod nie jest taki php początkujący, ani konkretnie pod PHP5, ani nie zaliczę go do php Pro

W wielu systemach jest problem ze stosowaniem tych samych znaczników w tych samych znacznikach znacznikach. Ku mojemu zaskoczeniu, nawet IPB nie radzi sobie z tym dobrze (w przeciwieństwie do phpBB):

Kod
<?php
echo "
"; // echo wyświetla [/ code]
?>[/code]

albo
Kod
[code]
[/code]
[ code][ code][/ code][/ code]


Próbuję ostatnie 4 dni napisać jakiś porządny skrypt, który będzie sprawdzał, czy [/ code] oznacza koniec kodu, czy to tylko jego część.

Powstało kilka różnych schematów, większość działała na zasadzie liczenia, ile otwieranych znaczników znajduje się pomiędzy pierwszym otwartym znaczniku i pierwszym zamykanym znaczniku, potem pętlą się dodaje do wyrażenia warunkowego znalezione znaczniki otwierające, oznacza się zmienną liczbę otwartych znaczników, potem pętla chodzi w nieskończoność, aż znajduje kolejne znaczniki (liczone od ostatniego wyrażenia, do znalezienia kolejnego [/ code]. Na razie zakładam, że użytkownik nie zapomniał zamknąć żadnego znacznika, potem to się dorobi. Ostatnia wersja, osiąga takie same cele co poprzednia, tylko ma troszkę mniej linijek (specjalnie dla IPB zmieniłem znacznik z [ code] na [cod]):
  1. <?php
  2. $a = '[cod][/cod] [cod][cod][/cod][/cod]';
  3. $a = '[cod][cod][/cod][cod][/cod][/cod]';
  4.  
  5. while (preg_match('#[cod].*?[/cod]#si',$a)) {
  6. $open_tags = 1;
  7. unset($nextLoop);
  8. $regexp = '#[cod](.*?)[/cod]#si';
  9.  
  10. while ($open_tags != 0) {
  11.  
  12. preg_match($regexp,$a,$i);
  13. $count = count(explode('[cod]',$i[1])) - 1;
  14.  
  15. $buffer = '';
  16. for ($i = 1; $i <= $count; $i++) {
  17. $buffer .= '.*?[cod]';
  18. }
  19.  
  20. if (isset($nextLoop)) {
  21. $open_tags += $count;
  22. }
  23. else {
  24. $nextLoop = '';
  25. $open_tags = $count;
  26. }
  27. $i = preg_replace('#(.*?)#',$buffer.'.*?[/cod](.*?)',$regexp);
  28.  
  29.  
  30. if (preg_match($i,$a)) {
  31. if ($open_tags == 0) {
  32. break;
  33. }
  34. $open_tags--;
  35. $regexp = $i;
  36. }
  37. }
  38. $a = preg_replace($regexp,'kod',$a,1);
  39. }
  40. echo $a;
  41. ?>


Jeżeli znaczniki są w stylu: "ciągle otwieramy a potem zamykamy" to skrypt radzi sobie z tym wspaniale, niestety, jeżeli namotamy mu, to gubi jakiś jeden zamykający.

Poniżej publikuje także tą metodę klasy bbCode, nie wiem jak działa, bo dawno nie sprawdzałem, a może komuś przyda się w udzieleniu odpowiedzi:

  1. <?php
  2. private function superWhile($start,$end,$alternate_start = '') {
  3. if ($alternate_start) {
  4. $start = '('.$start.'|'.$alternate_start.')';
  5. }
  6. else {
  7. $start = '('.$start.')';
  8. }
  9.  
  10. while (preg_match('#'.$start.'(.*?)'.$end.'#si',$this -> content,$i)) {
  11. $buffer = '';
  12.  
  13. $count = count(preg_split($start,$i[2])) - 1;
  14. $open_tags = $count;
  15.  
  16. for ($y = 1; $y <= $count; $y++) {
  17. $buffer .= '.*?'.$end;
  18. }
  19. $buffer = $start.$buffer;
  20.  echo $open_tags;
  21. if ($open_tags != 0) {
  22. while (preg_match('#'.$buffer.'(.*?)'.$end.'#si',$this -> content,$i)) {
  23. $count = count(preg_split($start,$i[2])) - 1;
  24. $open_tags = $open_tags + $count - 1; // - 1
  25. $temp_buffer = '';
  26. for ($y = 1; $y <= $open_tags; $y++) {
  27. $temp_buffer .= '.*?'.$end;
  28. }
  29. $buffer .= $temp_buffer.'.*?'.$end;
  30. if ($open_tags == 0) {
  31. break;
  32. }
  33.  
  34. }
  35.  
  36. for (;$open_tags < 0; $open_tags++) {echo '_++_'; //.*?[/]
  37. // $buffer = preg_replace('#.*?[/]$#si','',$buffer);
  38. $buffer = preg_replace('#.*?'.preg_quote($end).'$#si','',$buffer);
  39.  
  40. }
  41.  
  42. for (;$open_tags > 0; $open_tags--) { echo '_--_';
  43. // $buffer = preg_replace('#^[].*?#si','',$buffer);
  44. $buffer = preg_replace('#^'.preg_quote($end).'.*?#si','',$buffer);
  45. }
  46.  
  47. }
  48. else {
  49. $buffer .= '.*?'.$end;
  50. }
  51.  
  52. preg_match('#('.$buffer.')#si',$this -> content,$i);
  53. $uniqID = uniqid(rand(),TRUE);
  54. $this -> exploded[$uniqID] = $i[1];
  55. $this -> content = preg_replace('#'.$buffer.'#si',$uniqID,$this -> content,1);
  56. }
  57. }
  58. ?>
tiraeth
Pobierz preg_match'em zawartość [CODE][/CODE] a następnie narzuć mu addslashes smile.gif i sparsuj, dopiero na końcu użyj stripslashes i po sprawie...

Przenoszę: Skrypty php -> php
Krzychur
Sory tiraeth, nie za bardzo zrozumiałem Twojego posta, mógłbyś bardziej go rozszerzyć?

Jeżeli mam go rozumieć dosłownie, to byłbym bardzo pozytywnie zaskoczony, gdyby coś takiego działało, tyle że atom pomiędzy [code ] a [/code ] może zawierac dużo znaczków [code ] ale mimo to szuka do pierwszego [/code ]
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.