[PHP] preg_replace en rook uit mijn hoofd

Pagina: 1
Acties:

  • HappyChainsaw
  • Registratie: Januari 2002
  • Niet online

HappyChainsaw

It's a trick. Get an axe.

Topicstarter
Hai groep,

Al avonden ben ik aan het stoeien met het volgende. Veel reg expr. tutorials gelezen en gezocht, maar ik kom net niet uit het laatste stukje.
Ik wil in een string (vaak een lap tekst met HTML-tags) alle woorden die overeenkomen met een zoekterm highlighten. Die woorden moeten case-insenstive gematched worden, waarbij ze ook los in de tekst moeten staan. Dus niet onderdeel uitmaken van een ander woord. Het highlighten daar ben ik wel uit, alleen werkt het zoeken nog niet perfect.

Tot nu toe ben ik tot hier gekomen (versie PHP 4.1.2):
PHP:
1
$string = preg_replace("|($search)(?!\s)(?=[ ;?,!.\s])|i","$startstylesheetinfo$1$endstylesheetinfo",$string );

(?!\s) zou moeten checken of de match voorafgegaan wordt door een whitespace karakter;
(?=[ ;?,!.\s]) zou moeten checken of de match gevolgd wordt door een spatie, punt-komma, etc.

Alleen werkt het niet goed. Als ik in de string "Es desse dest, bes es Es Es, zes." zoek op "es", dan krijg ik:

Afbeeldingslocatie: http://www.chello.nl/~s.bontje/result01.gif

Waarschijnlijk staat er toch ergens een haakje verkeerd maar ik zie het niet meer... kan iemand zijn licht hierop laten schijnen?

Reuze bedankt, Sander


edit:
typo

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier


  • Grum
  • Registratie: Juni 2001
  • Niet online
Die woorden moeten case-insenstive gematched worden, waarbij ze ook los in de tekst moeten staan. Dus niet onderdeel uitmaken van een ander woord.
oftewel ervoor moet: begin van de regel of een non-word-char
erachter moet: non-word-char of het einde van de regel

^,\W,$

Daarmee moet je het toch wel kunnen ? :D

Verwijderd

\b($search)\b

\b = word boundary

Verwijderd

HappyChainsaw schreef op 24 september 2002 @ 18:54:
[...]
Tot nu toe ben ik tot hier gekomen (versie PHP 4.1.2):
PHP:
1
$string = preg_replace("|($search)(?!\s)(?=[ ;?,!.\s])|i","$startstylesheetinfo$1$endstylesheetinfo",$string );

(?!\s) zou moeten checken of de match voorafgegaan wordt door een whitespace karakter;
(?=[ ;?,!.\s]) zou moeten checken of de match gevolgd wordt door een spatie, punt-komma, etc.
ik ben geen regex-guru (wil t wel worden :P) maar je doet
PHP:
1
(?!\s)(?=[ ;?,!.\s])


wat wil je daar precies mee bereiken? de volgende karakters niet vinden: ;?,!.\s,
als die vooraf zijn gegaan door een \s :?
Note that the apparently similar pattern
(?!foo)bar
does not find an occurrence of "bar" that is preceded by
something other than "foo";
Op deze manier, heb je eigenlijk 2 stukjes, namelijk ($search) en (?!\s)(?=[ ;?,!.\s]) en dit lijkt mij niet goed.

Heb je al iets geprobeerd zoals:

PHP:
1
"/(?!\s)($search)(?=[ ;?,!.\s])/i"; // edit: wat aangepast, aangezien een (?!) voor het subject moet staan.


edit: gebruik maken van word boundary is wellicht een stuk makkelijker ;)

  • HappyChainsaw
  • Registratie: Januari 2002
  • Niet online

HappyChainsaw

It's a trick. Get an axe.

Topicstarter
Wow, ik ben even eten en wat een reacties! Geweldig, bedankt!

Ik ga alle tips na en laat weten hoe het verder verloopt.

  • HappyChainsaw
  • Registratie: Januari 2002
  • Niet online

HappyChainsaw

It's a trick. Get an axe.

Topicstarter
Hebbes!

Dit doet het werk:
PHP:
1
2
preg_replace("/\b($search)\b/i","$1",$string ); 
// NB stylesheet strings om $1 tbv leesbaarheid weggelaten


Bedankt!

Nu duik ik eens in dat tag <> verhaal.

  • HappyChainsaw
  • Registratie: Januari 2002
  • Niet online

HappyChainsaw

It's a trick. Get an axe.

Topicstarter
Bovenstaand werkt alleen als het woord binnen een word boundary valt. Dus een woord wat je wilt hekennen en tussen tags staat, bijvoorbeeld <tag>Cliënt</tag>, werd overgeslagen.

Dit pakt ze wel, een ook meteen de HTML-varianten van speciale karakters.
PHP:
1
2
$searchhtml = htmlentities($search);
$text = preg_replace("/\b(($search)|($searchhtml))\b/i","$newstringstart$1$newstringend",$string);

Als je met deze code zoekt op "Cliënt" in de string "Cliënt Cliënt <tag>Cliënt</tag> <tag>Cliënt </tag> <tag>Cliënt</tag>" dan worden ze allevier gevonden.

[ Voor 0% gewijzigd door HappyChainsaw op 24-09-2002 23:19 . Reden: het kon korter, en het is laat want een groot verschil met mijn eerdere bericht zie ik ook niet eigenlijk 8)7 ]


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Netjes dat je dat nog even meldt :)

  • HappyChainsaw
  • Registratie: Januari 2002
  • Niet online

HappyChainsaw

It's a trick. Get an axe.

Topicstarter
Dank :-)
Pagina: 1