[PHP/preg_replace]Highlighten keywords

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hier weer een post over het highlighten van keywords.
Ik heb de laatste dagen al heel veel post gelezen hierover en al verschillende code uitgeprobeerd.

De best werkende is volgens mij:
[PHP] gezochte woorden een kleur geven

Deze gebruik ik dan ook als mijn basis. Het gaat redelijk goed maar nog niet helemaal.

Eerst maar wat code:
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
function hilite_word ($word, $classIndex)
{
   return sprintf ( 
      '<span class="highlight%d">%s</span>', 
      1+$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 . ');'
         ),
         $subject
      );
   }
   return $subject;
}

function html_hilite ($keywords, $subject) 
{
   $patterns = array ();
   $quoted = array ();
   foreach ( $keywords as $keyword ) 
   {
      $keyword = trim($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 );
} 

Test code om het te starten:
PHP:
1
2
3
4
5
6
7
8
9
10
$somehtml ="
<div>
   <span class=\"piet\">
      Ko's liet <a href=\"piet.html\">PIET</a> 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>";

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


Wat gelukkig wel werkt is dat de html-tags worden overgeslagen, maar niet alle woorden worden gevonden.
Het resultaat van bovenstaand voorbeeld is:
Ko's liet PIET uit wandelen een schreeuwde: piet! mooie class in je span! en die div is ook niet mis! mooi gequote s"an
De onderstreepte woorden zijn de gevonden worden. Zoals je ziet zijn Ko's en PIET niet gevonden.
Verander ik nu in de zoekarray 'piet' met 'PIET' dan wordt PIET ook gevonden, maar Ko's nog steeds niet.
Probeer ik het nu in mijn 'echte' gegevens, dan is de tekst:
HTML:
1
2
3
<td class="kolom1"><a href="viewKlant.php?ID=6&bedrijfsnaam=Agrico">Agrico</a></td>
<td class="kolom2">Emmeloord</td>
<td class="kolom3">Nederland</td>

De zoekterm is Agrico en het resultaat is dan:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<td class="kolom1"><a href="viewKlant.php?ID=6&bedrijfsnaam=Agrico">
<span class="highlight1"></span>
<span class="highlight1"></span>
Agrico
<span class="highlight1"></span>
<span class="highlight1"></span>
</a></td>
<td class="kolom2"><span class="highlight1"></span>
<span class="highlight1"></span>
Emmeloord
<span class="highlight1"></span>
<span class="highlight1"></span></td>
<td class="kolom3"><span class="highlight1"></span>
<span class="highlight1"></span>
Nederland
<span class="highlight1"></span>
<span class="highlight1"></span></td>

dat lijkt me ook niet helemaal de bedoeling.
Ik kom er niet uit. Het zal wel weer iets kleins zijn wat ik over het hoofd zie.

Heeft iemand nog een suggestie?
Alvast bedankt.

--
Paul

Acties:
  • 0 Henk 'm!

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

drm

f0pc0dert

Hoi :) Ik voel me natuurlijk een beetje verantwoordelijk om te reageren. 't Zit 'm in regel 36, die regex die daar gemaakt wordt is niet case sensitive.

Hoe je aan die lege span's komt in je resultaat code weet ik niet, dat heeft waarschijnlijk met de input array te maken.

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


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dat begrijp ik niet helemaal.
Op regel 36 staat
code:
1
$mn = '/' . implode ( '|', $quoted ) . '/';

Bedoel je niet regel 34:
code:
1
$patterns[]= '/\b' . preg_quote ( $keyword ) . '\b/i';

Die /i betekent toch dat het case-insensitive is? Maar dat moet toch ook?

Misschien wil je het me nog een beetje duidelijker maken. Regex is niet mijn sterkste kant.

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

drm

f0pc0dert

Ik zie dat ik 't niet goed zei. De regex op regel 36 is juist wel case sensitive terwijl hij dat niet moet zijn. Kortom, het 'i'tje erbij en dan moet het werken.

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


Acties:
  • 0 Henk 'm!

  • assass
  • Registratie: November 2002
  • Laatst online: 31-07-2024

assass

Salon GoT'er

krijg je dan

code:
1
 $mn = '/' . implode ( '|', $quoted ) . '//i';


??