Autor Zpráva
Iggy
Profil *
potřebuju podbarvit v html textu (uložen v db) výskyt slova, ale aby se barvilo jen mezi tagy:
splácal jsem tohle, ale barví to jen jeden výskyt slova (pochopitelně - i dokonce vím proč, ale nevím jak to napravit):

 [>][^<]*)($nalezeno)([^>]*[<]


Takže jak udělat:
- aby to barvilo všechny výskyty?


A druhý problém je sestrojit ekvivalent do mysql, protože:
regexp  '(&gt;)([^&lt;]*)(".$slovo.")([^&gt;]*)(&lt;)'

nejde - "<" ">" se najednou chovají jako více znakové slovo

Děkuji všem!
Iggy
Profil *
upřesnění:

první problém je barvení při výpisu v php (text už je převeden na html entity)
druhý problém je hledání v db, jestli tam vůbec text je :)

regulární výrazy jsou obdobné....
Iggy
Profil *
upřesnění 2:

první regulární výraz je pochopitelně
 "([>][^<]*)($nalezeno)([^>]*[<])"


Omlouvám se za zmatky už při vložení (to když to člověk dělá ve spěchu)
venca12
Profil
Ahoj,

nebylo by lepší, pro obarvení slova použít až při výstupu php, třeba funkci explode. Myslím, pokud bych chtěl například nalezený text zvýraznit tučně, použít to například takto:

$textNatazenyZDb = 'ahoj, ja jsem franta vomacka z otrokovic';
$nalezeneSlovo = 'franta';
// exploduju to podle nalezeneho slova a v zapeti zase imploduju otucnenym slovem
$obarvenyText = implode("<b>$nalezeneSlovo</b>", explode($nalezeneSlovo, $textNatazenyZDb));


Chápu, že se ti to nemusí líbit, protože toto řešení není tak sexy, jako použití regulárních výrazů. Předpokládám, že aby tvůj regulární výraz barvil všechna slova měl by projít celý požadovaný řetězec.

Pokud uvažuju o tom, že použiju v php funkce pro regulární výrazy perlovského typu měl bych například místo funkce preg_match, použít funkci preg_match_all, která najde všechny výskyty hledaného řetězce v textu a vrátí jejich počet, případně nalezené řetězce, předané odkazem v parametru $matches.

Ty ale zřejmě budeš chtít provést pomocí regulárrních výrazů, ne hledání (match), ale náhradu, například pomocí funkce preg_replace. K tomu, aby došlo k nahrazení úplně všech řetězců a ne pouze prvního, je potřeba použít modifikátor e, za regulárrním výrazem. Mrkni na jeho použití na http://cz2.php.net/manual/en/function.preg-replace.php v příkladu #4.

Dá se očekávat, že při použití v MySQL, bude též nutné použít modifikátor.

Btw. je divné, že máš v databázi uložené entity (zřejmě tam někde před uložením používáš funkci htmlspecialchars nebo htmlentities), to není dobré, protože se ti tak data v databázi deformují a špatně se s nimi pracuje, viz tvůj problém. Použití funkce htmlspecialchars, by mělo být provedeno až při výstupu dat do webu. Jinak více o tom píše Jakub Vrána na svém webu http://php.vrana.cz/escapovani.php
Iggy
Profil *
děkuji za obsáhlý příspěvek a za mnoho tipů,

děkuji!
Iggy
Profil *
$obarvenyText = implode("<b>$nalezeneSlovo</b>", explode($nalezeneSlovo, $textNatazenyZDb));

tady je problém, když někdo zadá do vyhledávání např. img, tak se naleznou i značky v html tagách... nebo se pletu?
orava))
Profil *
ano najdu sa tak to staci iba predtym osetrit HTML tagy
Iggy
Profil *
u sa tak to staci iba predtym osetrit HTML tagy

to dost dobře nechápu, když to chci na stránce zobrazit (html text, kde jsou podbarvené slovy vyhledání - nikoliv v tagách), tak přeci chci zachovat formát html, jen provést náhradu mimo tagy.

Tak jak by mě řešení bez reg. výrazu situaci ulehčilo?
venca12
Profil
Iggy ano, to máš pravdu, to jsem nedomyslel.

V tom případě se to trochu zkomplikuje.

$textNatazenyZDb = 'ahoj, ja jsem <franta name="franta">franta</franta> vomacka z otrokovic';
$nalezeneSlovo = 'franta';

$vysledek = '';
$tmp = '';
$castiTextu = explode($nalezeneSlovo, $textNatazenyZDb);
for($i = 0; $i < count($castiTextu); $i++)
{
	$highlight = '';
	$tmp .= $castiTextu[$i];
	// abych nepripojil hledany retezec i na konec vysledku
	if($i != count($castiTextu) - 1)
	{
		$posLt = strrpos($tmp, '<');
		$posGt = strrpos($tmp, '>');
		if(($posLt === false ? -1 : $posLt) > ($posGt === false ? -1 : $posGt))
			$highlight = $nalezeneSlovo;
		else
			$highlight = "<b>$nalezeneSlovo</b>";
	}
	
	$vysledek .= $castiTextu[$i].$highlight;
}
unset($castiText, $tmp, $highlight, $postGt, $postLt, $i);

echo htmlspecialchars($vysledek);


Možná by bylo vhodnější k procházení pole použít místu cyklu for nějakou funkce k práci s poli http://cz2.php.net/manual/en/ref.array.php ale to bych musel hledat.

Pravděpodobně ve světle nových skutečností, bude použití regexpu vhodnější.
nikola
Profil *
ahojte plsky jak zadám v html kodu vyhledávání?sem už uplně bezradná díky

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: