[PHP] gezochte woorden een kleur geven

Pagina: 1
Acties:
  • 120 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik ben even aan het prutsen met een stukje code waarmee ik mijn gevonden zoek resultaten kan "highlighten" (in deze teksten kunnen zowel hoofdletters als kleine letters zitten)...

toen kreeg ik steeds errors bij tekens als *,?,+ en ]
die heb ik nu gereplaced... maar nu heb ik (voor zover ik weet) alleen nog problemen met slash en backslash...

bij slash word de html van de pagina verpest

bij backslash:
Warning: No ending delimiter '/' found in

hieronder even de code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    // zoekterm kleuren
    if(!empty($_POST['zoekterm'])){
    $zoek = trim($_POST['zoekterm']);
    $zoek = str_replace("[", "\\[", $zoek);
    $zoek = str_replace("^", "\^", $zoek);
    $zoek = str_replace("$", "\$", $zoek);
    $zoek = str_replace(".", "\.", $zoek);
    $zoek = str_replace("|", "\|", $zoek);
    $zoek = str_replace("?", "\?", $zoek);
    $zoek = str_replace("*", "\*", $zoek);
    $zoek = str_replace("+", "\+", $zoek);
    $zoek = str_replace("(", "\(", $zoek);
    $zoek = str_replace(")", "\)", $zoek);
    $zoek = str_replace("<", htmlspecialchars("<"), $zoek);
    $zoek = str_replace(">", htmlspecialchars(">"), $zoek);

    $woord = $bericht;

    $bericht = preg_replace("/$zoek/i", "<font style=\"color:black;background-color:#B1D3F5\">\\0</font>", $woord);
    }


nu moet ik denk ik die backslash nog escapen ofzoiets ( :? ) en met slash wat doen maar ik kom er niet uit...

iemand een oplossing of een hele andere manier die beter is?

[ Voor 16% gewijzigd door Verwijderd op 03-06-2004 15:47 ]


Acties:
  • 0 Henk 'm!

  • R_W
  • Registratie: Oktober 2002
  • Niet online

R_W

/ wordt \/ en \ wordt \\ :)

Of je doet:

PHP:
1
str_replace( $zoek, "<font enzo>" . $zoek . "</font>", $text );

[ Voor 64% gewijzigd door R_W op 03-06-2004 15:50 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Ja, gebruik om te beginnnen
str_ireplace (http://nl.php.net/manual/en/function.str-ireplace.php), je bent nu een reguliere expressie aan het doen zonder reden...

Hoe het zit met speciale karakters kun je vast op die link vinden

---
Bovendien kun je ook enkele quotes gebruiken en eventuele variabelen via "' . $var . '" even invoegen. Je hoeft dan de dubbele quotes alvast niet meer te "escapen"

[ Voor 110% gewijzigd door Verwijderd op 03-06-2004 15:56 ]


Acties:
  • 0 Henk 'm!

  • daaan
  • Registratie: Maart 2000
  • Laatst online: 04-09 13:13

daaan

Brandweer Zoutkamp

Ok R_W, ik haal nog even koffie :+

[ Voor 109% gewijzigd door daaan op 03-06-2004 15:57 ]

One's never alone with a rubber duck.


Acties:
  • 0 Henk 'm!

  • R_W
  • Registratie: Oktober 2002
  • Niet online

R_W

daaan schreef op 03 juni 2004 @ 15:53:
Even googlen:

PHP:
1
2
3
4
5
6
7
function highlight_words( $tekst, $woorden )
{
    foreach( $woorden as $woord )
   {
        $tekst = preg_replace( "/$woord/i", '<span style="color:red;font-weight:bold;">' .$woord . '</span>', $tekst ); 
    }
return( $tekst );

}
Startpost ook gelezen?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
R_W schreef op 03 juni 2004 @ 15:49:
/ wordt \/ en \ wordt \\ :)

Of je doet:

PHP:
1
str_replace( $zoek, "<font enzo>" . $zoek . "</font>", $text );
als ik doe:
$zoek = str_replace("/", "\/ ", $zoek);

dan krijgt / geen kleur als ik hierop zoek

en :
$zoek = str_replace("/", "// ", $zoek);

dat kan dus niet...


met str_replace kleurt alleen wat je prcies intypt

dus als er in de tekst staat: Bla
en ik typ: bla

dan krijgt dit woord geen kleur

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op 03 juni 2004 @ 15:52:
Ja, gebruik om te beginnnen
str_ireplace (http://nl.php.net/manual/en/function.str-ireplace.php), je bent nu een reguliere expressie aan het doen zonder reden...

Hoe het zit met speciale karakters kun je vast op die link vinden

---
Bovendien kun je ook enkele quotes gebruiken en eventuele variabelen via "' . $var . '" even invoegen. Je hoeft dan de dubbele quotes alvast niet meer te "escapen"
dat werkt alleen bij php5 (ik heb php 4.2.3)

Acties:
  • 0 Henk 'm!

  • R_W
  • Registratie: Oktober 2002
  • Niet online

R_W

PHP:
1
2
3
4
5
6
7
8
<?

$text = "blaatpomti/domblaat";
$zoek = "pomti/dom";
$zoek = str_replace("/", "\/", $zoek);
echo preg_replace("/$zoek/i", "<font style=\"color:black;background-color:#B1D3F5\">\\0</font>", $text);

?>


Werkt gewoon hoor...

Acties:
  • 0 Henk 'm!

  • Speedener
  • Registratie: September 2000
  • Laatst online: 18-09 12:54
Ik heb dit ook ooit geprobeerd, en het werkte. Tot ik erachter kwam dat een link het niet meer deed als het zoekwoord in de url van die link stond. Denk daaraan ;)

Zijn daar ook oplossingen voor ?

[ Voor 5% gewijzigd door Speedener op 03-06-2004 16:09 ]

LG Therma V Split WP: HU143MA.U33-HN1636M NK5


Acties:
  • 0 Henk 'm!

  • Thijsmans
  • Registratie: Juli 2001
  • Laatst online: 21:35

Thijsmans

⭐⭐⭐⭐⭐ (5/5)

Ja, je zou kunnen bijhouden of je binnen een on-afgesloten "<" zit --> in een tag zit. Maar dan moet je met tokens/chars gaan werken, wat de snelheid niet ten goede komt.

Als je trouwens toch met regexp's bezig bent, je kan hem ook zo in elkaar zetten dat je niet in tags matcht. Vraag me alleen niet hoe :+

Privacy-adepten vinden op AVGtekst.nl de Nederlandse AVG-tekst voorzien van uitspraken en besluiten.


Acties:
  • 0 Henk 'm!

  • MatHack
  • Registratie: Oktober 2001
  • Niet online

MatHack

Dev by day, Gamer by night

R_W schreef op 03 juni 2004 @ 16:03:
PHP:
1
2
3
4
5
6
7
8
<?

$text = "blaatpomti/domblaat";
$zoek = "pomti/dom";
$zoek = str_replace("/", "\/", $zoek);
echo preg_replace("/$zoek/i", "<font style=\"color:black;background-color:#B1D3F5\">\\0</font>", $text);

?>


Werkt gewoon hoor...
In plaats van die str_replace en dan / vervangen met \/ kun je beter gebruik maken van preg_quote().

There's no place like 127.0.0.1


Acties:
  • 0 Henk 'm!

  • R_W
  • Registratie: Oktober 2002
  • Niet online

R_W

Met Regular Expressions aangeven dat niets binnen < en > mag worden vervangen.

offtopic:
Bij Fok.nl hebben ze daar geen rekening mee gehouden |:(

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
R_W schreef op 03 juni 2004 @ 16:03:
PHP:
1
2
3
4
5
6
7
8
<?

$text = "blaatpomti/domblaat";
$zoek = "pomti/dom";
$zoek = str_replace("/", "\/", $zoek);
echo preg_replace("/$zoek/i", "<font style=\"color:black;background-color:#B1D3F5\">\\0</font>", $text);

?>


Werkt gewoon hoor...
hmz jah ik was even iets te gehaast er stond een spatie achter bij mij

maar nu die backslash nog...
want:
$zoek = str_replace("\", "\\", $zoek);

dat kon dus niet...

[ Voor 19% gewijzigd door Verwijderd op 03-06-2004 16:36 ]


Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 19-09 22:18

chem

Reist de wereld rond

Waarom gebruik je niet gewoon preg_quote ?

Daarbij staat er op dit forum een post van mij met een dergelijke vraag + antwoord met een dubbele regexp.

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • Skaah
  • Registratie: Juni 2001
  • Laatst online: 16-09 18:38
HTML-safe, $keywords is een array met de woorden die je wilt highlighten. Chem heeft aan de basis van deze functie gestaan, btw. _/-\o_ Chem!
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function highlight($keywords,$string)
{
        $styles = array('color: #fff; background-color: #909;',
                        'color: #000; background-color: #ff6;',
                        'color: #000; background-color: #aff;',
                        'color: #000; background-color: #9f9;',
                        'color: #000; background-color: #f99;',
                        'color: #000; background-color: #f6f;',
                        'color: #fff; background-color: #800;',
                        'color: #fff; background-color: #0a0;',
                        'color: #fff; background-color: #860;',
                        'color: #fff; background-color: #049;',
        );

        foreach($keywords as $keyword)
        {
                $style = next($styles);
                if (!$style)
                {
                        $style = reset($styles);
                }
                $string = preg_replace("/(>|^)([^<]+)(?=<|$)/esx",
                                       "'\\1'.preg_replace('!\b(".preg_quote($keyword).")\b!i','<span style=\"background-color: ".$style.";font-weight: bold;\">".$keyword."</span>','\\2')",
                                       $string);
        }
        return $string;
}


Deze functie heeft btw nog één bugje: als er hoofdletters in de bron staan in het woord dat je wilt highlighten, worden de hooftletters vervangen door lowercase letters. Dit omdat ik het niet voor elkaar krijg om een backreference van een preg_replace in een preg_replace te gebruiken.

[ Voor 32% gewijzigd door Skaah op 03-06-2004 19:22 ]


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Skaah:
HTML-safe, $keywords is een array met de woorden die je wilt highlighten. Chem heeft aan de basis van deze functie gestaan, btw. _/-\o_ Chem!
PHP:
1
// snip


Deze functie heeft btw nog één bugje: als er hoofdletters in de bron staan in het woord dat je wilt highlighten, worden de hooftletters vervangen door lowercase letters. Dit omdat ik het niet voor elkaar krijg om een backreference van een preg_replace in een preg_replace te gebruiken.
De woorden worden vervangen door de woorden die als parameter meegegeven zijn, bedoel je. Stel je zoekt op woorden met alleen maar hoofdletters: dan komen die woorden ook terug als gehilite, niet het origineel :)

Verder moet je bij preg_quote ook de delimiter opgeven, anders wordt de delimiter niet escaped. (Tenzij je de / als delimiter gebruikt)

Verder heb je met de /e modifier nog wel eens gedonder met quotes. Daarom zou ik die zoveel mogelijk vermijden en preg_replace_callback gebruiken. Verder is het allemaal een stukje beter te lezen en te onderhouden als je met een preg_split ipv preg_match de tags eruit filtert (imho):

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
define ( 'HILITE_CLASSES_MAX', 10 );

function hilite_word ( $word, $classIndex ) {
   return sprintf ( 
      '<span class="hilite-%c">%s</span>', 
      97 + $classIndex, 
      $word
   );
}

function hilite ( $patterns, $subject ) {
   foreach ( $patterns as $nr => $pattern ) {
      $subject = preg_replace_callback ( 
         $pattern,
         create_function (
            '$matches',
            'return hilite_word ( $matches[0], ' . $nr % HILITE_CLASSES_MAX . ');'
         ),
         $subject
      );
   }
   return $subject;
}

function html_hilite ( $keywords, $subject ) {
   $patterns = array ();
   $quoted = array ();
   foreach ( $keywords as $keyword ) {
      $quoted[]= preg_quote ( $keyword );
      $patterns[]= '/\b' . preg_quote ( $keyword ) . '\b/i';
   }
   $mn = '/' . implode ( '|', $quoted ) . '/';
   
   $parts = preg_split ( '/(<[^>]+?>)/s', $subject, -1, PREG_SPLIT_DELIM_CAPTURE );
   foreach ( $parts as $i => $text ) {
      // die strlen () en preg_match () calls hier zijn optimalisaties.
      // als je ze weglaat scheelt dat behoorlijk wat
      if ( $text {0} != '<' && strlen ( trim ( $text ) ) && preg_match ( $mn, $text ) ) {
         $parts[$i] = hilite ( $patterns, $text );
      }
   }
   return implode ( '', $parts );
}

$somehtml =<<<EOHTML
<div>
   <span class="piet">
      Ko's liet PIET uit wandelen een schreeuwde: 
      <q>piet! mooie class in je span! en die div is ook niet mis!</q>
      <q>mooi gequote s"an</q>
   </span>
</div>
EOHTML;

echo html_hilite ( array ( 's"an', 'div', 'piet', 'ko\'s' ), $somehtml );

Tot slot gebruik ik, zoals je ziet, liever classes dan CSS in de php-code.
De css die jouw code uitpoept is ook niet helemaal jofel, kijk maar 's goed :P

Oh, en na wat optimalisatie is deze ook een tikkie sneller.

Wat 'm nog sneller zou maken is ipv een foreach () te gebruiken de woorden in 1 regex zetten door middel van 't pipe symbol:
code:
1
2
3
4
5
   $quoted = array ();
   foreach ( $keywords as $keyword ) {
      $quoted[]= '\b' . preg_quote ( $keyword ) . '\b';
   }
   $pattern = '/' . implode ( '|', $quoted ) . '/';

't Nadeel daarvan is dat je weer lastig verschillende kleuren bij verschillende woorden kunt gebruiken.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz

Pagina: 1