ugrás a tartalomhoz

String ellenőrzés

Abzu · 2008. Dec. 30. (K), 18.16
Adott egy fórum, és ott hozzászólás lehetősége. A hozzászólásokat szeretném ellenőrizni, hogy nyisson meg a felhasználó tagokat, amiket nem zár le. Tehát ha egy [b]-t megnyit és nem zár le akkor ne legyen félkövér a többi. Gondoltam hogy megszámoltatom a nyitó és a záró tagokat, és az egyezik akkor jó, de nem jó, mert kezdhet záróval, és nyitóval fejezi be. Tehát valami összetettebb dolog kellene.
Gondoltam olyasmire, hogy a string minden karaterét vizsgálom és magam döntöm el hogy nyit-e és zár-e, de ha lehet akkor jobb lenne egyszerűbb
 
1

Több megoldás lehetséges

Nagy Gusztáv · 2008. Dec. 30. (K), 22.47
Ha a kezdő-záró sorrend az érdekes, akkor egyetlen segédváltozóval végigmész, ha nyitó jön, akkor növeled, ha záró, csökkented. Ha negatívba megy, vagy a végére nem 0, akkor hiba.

Ha a helyes egymásba-ágyazásra akarsz figyelni, akkor pedig kell egy verem (vagy tömb), amibe belepakolsz minden nyitó esetén, és kiveszel záró esetén.
3 hibalehetőség:
- a végére nem ürül ki a verem: hiányzik néhány záró tag
- nem az van a verem tetején, amit éppen ki akarsz venni: rossz az egymásba ágyazás
- üres veremnél ki kellene venni valamit: hiányzik a nyitó tag

Off: kedvenc órai programozás feladataim közé tartozik a témakör :-)
2

quick'n'dirty

numen · 2008. Dec. 31. (Sze), 01.40
én egyszerűen csak regexpcserével oldottam meg a dolgot: a \[b\](.*)?\[/b\] -t cserélem le a <b>$1</b> -re...
az én megoldásom gyors és egyszerű, kerüli a vermet, cserébe az általad említett problémára megoldást kínál.
Ellenben a nesting hibákat nem védi ki, szóval ha komolyabbat akarsz, marad a verem.
3

Én annó írtam js-t

Ustak · 2008. Dec. 31. (Sze), 20.38
ami a "fékövér" gombra kattintva a kijelölt szöveg köré illesztette a két tagot, és így nem az user írta be. (Persze az ellenőrzés akkor is fontos :-) )
4

Nem kell hozzá verem,

Fraki · 2008. Dec. 31. (Sze), 21.27
Nem kell hozzá verem, rekurzívan is lehet csinálni.
  1. class bbcode {  
  2.   
  3.     private function callback($m) {  
  4.         return "<{$m[1]}>" . self::replace($m[2], array($m[1])) . "</{$m[1]}>";  
  5.     }  
  6.       
  7.     public function replace($input$tags) {  
  8.         foreach ($tags as $tag) {  
  9.             $input = preg_replace_callback('#\[('.$tag.')](.*)\[/'.$tag.']#'array(self, 'callback'), $input);  
  10.         }  
  11.         return $input;  
  12.     }  
  13.   
  14. }  
  15.   
  16. $in = 'Lorem [/b]ipsum <span style="font-weight:bold">dol[b]or</span> <span style="font-style:italic">sit [i]amet[/b] consectetuer <span style="text-decoration:underline">quam </span>fringilla </span>malesuada [/u]elit [i]ut.';  
  17.   
  18. $out = bbcode::replace($inarray('b''i''u'));  
  19.   
  20. echo "<pre>$in<br>$out</pre>";  
Normálisan itt.
5

hibás

Hodicska Gergely · 2009. Jan. 1. (Cs), 17.21
1. self helyett 'self' kell.

2. Pont a lényeget nem tudja (ami miatt a verem szóba került), próbáld ki erre: Lorem [ i ]ipsum [ b ]dol[ /i ]or[ /b ].
6

Köszi. Volt benne még egy

Fraki · 2009. Jan. 2. (P), 06.30
Köszi.

Volt benne még egy hiba, (.*) helyett (.*?) kell.

Azért a posztbeli problémát kezeli (ne legyenek árva tagek).
A keresztbeágyazás szűrésének rekurzív verziója (némi overheaddel):
  1. class bbcode2 {  
  2.   
  3.     private static $tags;  
  4.     private static $tagsRe;  
  5.       
  6.     private function callback($m) {  
  7.         $repl = self::replace($m[2]);  
  8.         if (preg_match('#\[/?('. self::$tagsRe . ')]#'$repl)) {  
  9.             return $m[0];  
  10.         }  
  11.         return "<{$m[1]}>" . $repl . "</{$m[1]}>";  
  12.     }  
  13.   
  14.     private function replace($input) {  
  15.         foreach (self::$tags as $tag) {  
  16.             $re = '#\[(' . $tag . ')](.*?)\[/' . $tag . ']#';  
  17.             $input = preg_replace_callback($rearray('self''callback'), $input);  
  18.         }  
  19.         return $input;  
  20.     }  
  21.   
  22.     public function filter($input$tags) {  
  23.         self::$tags = $tags;  
  24.         self::$tagsRe = implode('|'$tags);  
  25.         return self::replace($input);  
  26.     }  
  27.   
  28. }  
  29.   
  30. $in = 'Lorem [i ]ip[u ]s[/u]um [b ]dol[/i]or[/b] [b ]si[u ]t[/u] am[/b]et';  
  31.   
  32. $out = bbcode2::filter($inarray('b''i''u'));  
  33.   
  34. echo "<pre>$in<br>$out</pre>\n\n";  
Lorem [i ]ip[u ]s[/u]um [b ]dol[/i]or[/b] [b ]si[u ]t[/u] am[/b]et
Lorem [i ]ipsum [b ]dol[/i]or[/b] sit amet
7

még két apróság

Hodicska Gergely · 2009. Jan. 2. (P), 21.17
Ha már statikus metódusokat használsz, akkor deklaráld is őket statikusnak (gyorsabb lesz a hívás), illetve a self-es téma kapcsán látszik, hogy kikapcsolt NOTICE-ok mellett fejlesztesz, ami eléggé rossz szokás, érdemes bekapcsolni.