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.

class bbcode {

	private function callback($m) {
		return "<{$m[1]}>" . self::replace($m[2], array($m[1])) . "</{$m[1]}>";
	}
	
	public function replace($input, $tags) {
		foreach ($tags as $tag) {
			$input = preg_replace_callback('#\[('.$tag.')](.*)\[/'.$tag.']#', array(self, 'callback'), $input);
		}
		return $input;
	}

}

$in = 'Lorem [/b]ipsum dol[b]or sit [i]amet[/b] consectetuer quam fringilla malesuada [/u]elit [i]ut.';

$out = bbcode::replace($in, array('b', 'i', 'u'));

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):

class bbcode2 {

	private static $tags;
	private static $tagsRe;
	
	private function callback($m) {
		$repl = self::replace($m[2]);
		if (preg_match('#\[/?('. self::$tagsRe . ')]#', $repl)) {
			return $m[0];
		}
		return "<{$m[1]}>" . $repl . "</{$m[1]}>";
	}

	private function replace($input) {
		foreach (self::$tags as $tag) {
			$re = '#\[(' . $tag . ')](.*?)\[/' . $tag . ']#';
			$input = preg_replace_callback($re, array('self', 'callback'), $input);
		}
		return $input;
	}

	public function filter($input, $tags) {
		self::$tags = $tags;
		self::$tagsRe = implode('|', $tags);
		return self::replace($input);
	}

}

$in = 'Lorem [i ]ip[u ]s[/u]um [b ]dol[/i]or[/b] [b ]si[u ]t[/u] am[/b]et';

$out = bbcode2::filter($in, array('b', 'i', 'u'));

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.