Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> paser bbCode
Krzychur
post 14.07.2005, 10:02:30
Post #1





Grupa: Zarejestrowani
Postów: 214
Pomógł: 0
Dołączył: 3.01.2004
Skąd: Łódź

Ostrzeżenie: (0%)
-----


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. ?>


--------------------
Go to the top of the page
+Quote Post
tiraeth
post 14.07.2005, 16:27:42
Post #2





Grupa: Przyjaciele php.pl
Postów: 1 789
Pomógł: 41
Dołączył: 30.10.2003
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
Krzychur
post 14.07.2005, 16:31:07
Post #3





Grupa: Zarejestrowani
Postów: 214
Pomógł: 0
Dołączył: 3.01.2004
Skąd: Łódź

Ostrzeżenie: (0%)
-----


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 ]


--------------------
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 27.04.2024 - 04:43