[PHP] preg_replace 'foutje'.

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Fles
  • Registratie: Augustus 2001
  • Laatst online: 06-04-2023
Ik probeer met preg_replace bepaalde woorden te markeren. Dit doe ik met de volgende functie.

PHP:
1
2
3
4
5
6
7
8
9
10
  function mark_words($search, $text)
  {
    $keywords = split(" ", $search);
    for ($ctr = 0; $keywords[$ctr] != NULL; $ctr ++)
    {
      $pattern[$ctr] = "#(.*?)($keywords[$ctr])(.*?)#si";
      $replace[$ctr] = '\1<font style="background-color: gray">\2</font>\3';
    }
    return preg_replace($pattern, $replace, $text);
  }


$search is de string woorden die gesplit zijn door een spatie. Later splits ik die in apparte woorden $keywords.

Als ik op een woord zoek en ik zoek daarachteraan nog op 'on' dan vervant hij het 'on' van de font die hij bij voorgaande woorden heeft neergezet.

Dus als ik zoek op bijvoorbeeld: 'forum on'
Dan zet hij in de text:

blablabla <f<font style="background: gray">on</font>t style="background: gray">forum</f<font style="background: gray">on</font>t> blabla

Hoe kan ik verhelpen dat hij niet ook gaat zoeken op de al vervangen delen?

Ik hoop dat het probleem duidelijk is.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
alleen preg_replacen als je niet je eigen constructie tegenkomt???

Acties:
  • 0 Henk 'm!

  • martinvw
  • Registratie: Februari 2002
  • Laatst online: 20-08 20:35
de match iets anders maken, bijvoorbeeld eisen dat er spaties om heen staan.

Acties:
  • 0 Henk 'm!

  • Fles
  • Registratie: Augustus 2001
  • Laatst online: 06-04-2023
Hmm, beetje lastig om uit te zoeken. Want ik moet de goede 'on' wel vervangen als ik die tegen kom. Of is hier een eenvoudige oplossing voor?
M4rt1nvW schreef op 10 March 2003 @ 20:18:
de match iets anders maken, bijvoorbeeld eisen dat er spaties om heen staan.
Zou kunnen, maar ik heb liever dat het niet nodig is dat er spaties om staan. En daar komt bij dat ik een beetje een perfectionist ben en op die manier zou het nog kunnen voor komen dat als je op een bepaalde string zoekt, hij het toegevoegde gaat vervangen.

[ Voor 63% gewijzigd door Fles op 10-03-2003 20:21 ]


Acties:
  • 0 Henk 'm!

  • Roa
  • Registratie: December 2002
  • Laatst online: 03-07-2024

Roa

Hmm, beetje lastig om uit te zoeken. Want ik moet de goede 'on' wel vervangen als ik die tegen kom. Of is hier een eenvoudige oplossing voor?
Om de goede 'on' staan toch spaties? dus dan kan dat toch gewoon???

Research is what I'm doing when I don't know what I'm doing.


Acties:
  • 0 Henk 'm!

  • Fles
  • Registratie: Augustus 2001
  • Laatst online: 06-04-2023
Roa schreef op 10 March 2003 @ 20:30:
[...]


Om de goede 'on' staan toch spaties? dus dan kan dat toch gewoon???
Die quote was nog een reactie op het bericht van Gomez12

Maar ik heb toch liever dat die spaties niet nodig zijn.

Acties:
  • 0 Henk 'm!

  • Roa
  • Registratie: December 2002
  • Laatst online: 03-07-2024

Roa

Dat is niet mogelijk, op dat probleem ben ik gestoten bij een bbscript waarin : ? (zonder spatie) een smilie is, en :?: ook, : ? werd dus de eerste smilie, en : stond erachteraan. Je moet dus echt zeggen dat er spatie, punt, komma of einde van een string staat:

/on(?=[\s.,]|$)/

\edit
De code klopt niet helemaal, je moet natuurlijk ook kijken of ervoor nog spaties e.d. staan.

Dat word dus zoiets als:

/(?=[\s.,]|$)on(?=[\s.,]|$)/

(ik heb nog niet zoveel ervaring met pcre, kleine disclaimer dus ;))

[ Voor 31% gewijzigd door Roa op 10-03-2003 20:44 ]

Research is what I'm doing when I don't know what I'm doing.


Acties:
  • 0 Henk 'm!

Verwijderd

Deze gebruik ik, en werkt voor zover prima...

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

$keyword = 'keyword';
$text = 'Dit is een keyword, genaamd "keyword" en hoort dus ook in een <a href="#">KEYWORD</a> link te staan in bold aka keyword.';
$text = preg_replace("/(>|^)([^<]+)(?=<|$)/esx", "'\\1' . eregi_replace('" . $keyword . "', '<b>" . $keyword . "</b>', stripslashes('\\2'))", $text);

echo '<hr>' . $text . '<hr>';

?>

Acties:
  • 0 Henk 'm!

  • Fles
  • Registratie: Augustus 2001
  • Laatst online: 06-04-2023
Je gebruikt 1 keyword en niet een array. Als ik deze ga omzetten hou ik hetzelfde probleem. Ik heb ook niet echt veel ervaring met preg dus ik moet nazoeken wat dit precies allemaal inhoud.

Acties:
  • 0 Henk 'm!

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

drm

f0pc0dert

Wat maakt 't voor verschil volgens jou, dat er in Markuz' voorbeeld geen array gebruikt wordt :? Wat is er mis met een simpele foreach? ;)

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


Acties:
  • 0 Henk 'm!

Verwijderd

drm schreef op 11 March 2003 @ 00:34:
Wat maakt 't voor verschil volgens jou, dat er in Markuz' voorbeeld geen array gebruikt wordt :? Wat is er mis met een simpele foreach? ;)
Als je een array in bijvoorbeeld strtr gebruikt, loopt hij maar een keer over de tekst heen, en vervangt niet wat je al vervangen hebt. Of dit ook in preg_replace mogelijk is weet ik niet.

[ Voor 2% gewijzigd door Verwijderd op 11-03-2003 01:04 . Reden: Lees de draad voor je blaat dus. ]


Acties:
  • 0 Henk 'm!

  • Fles
  • Registratie: Augustus 2001
  • Laatst online: 06-04-2023
Verwijderd schreef op 11 March 2003 @ 01:03:
[...]


Als je een array in bijvoorbeeld strtr gebruikt, loopt hij maar een keer over de tekst heen, en vervangt niet wat je al vervangen hebt. Of dit ook in preg_replace mogelijk is weet ik niet.
Aha, en dat werkt misschien nog wel makkelijker ook. Bedankt voor de tip. Ik d8 dat deze wel net zo wou werken als preg_replace. Dan wordt het dus zo iets als:

PHP:
1
2
3
4
5
6
7
8
9
  function mark_words($search, $text)
  {
    $keywords = split(" ", $search);
    for ($ctr = 0; $keywords[$ctr] != NULL; $ctr ++)
    {
      $pattern[$keywords[$ctr]] = "<font style='background-color: gray'>$keywords[$ctr]</font>";
    }
    return strtr($text, $pattern);
  }


Nu zit ik dus alleen met hoofdletters, die vervangt hij dan door niet hoofdletters. Is er een manier om dit te checke?

[ Voor 47% gewijzigd door Fles op 12-03-2003 13:24 ]


Acties:
  • 0 Henk 'm!

  • Roa
  • Registratie: December 2002
  • Laatst online: 03-07-2024

Roa

je zou eerst de hoofdletters kunnen aanpassen en daarna de kleine letter, tweede functie dus...Maar het is vast ook zonder wel mogelijk...

Research is what I'm doing when I don't know what I'm doing.


Acties:
  • 0 Henk 'm!

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

drm

f0pc0dert

Roa:
je zou eerst de hoofdletters kunnen aanpassen en daarna de kleine letter, tweede functie dus...Maar het is vast ook zonder wel mogelijk...
Hoe zie je dat dan voor je? Dat je alle combinaties van Keyword kEyword keYword etc. gaat uitproberen? Erg efficient is dat niet ....



Als je de case wilt bewaren van de keywords in de tekst is het toch veel makkelijker om het met preg_replace te doen. Zorg dat je enkel woorden vervangt die niet in html-tags voorkomen (redelijk eenvoudige regex), zodat je niet een f***-up layout krijgt als ik op bijvoorbeeld 'div' of 'body' zoek... Ik weet overigens niet in hoeverre je in HTML zoekt, maar dat even daar gelaten...

Als je met preg_replace vervangt, kun je namelijk refereren aan het gedeelte wat je matcht met een zgn. backreference:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$keywords = array_unique ( $keywords );
foreach ( $keywords as $keyword ) {
   $keyword = preg_quote ( htmlentities ( $keyword ) );
   $body = preg_replace ( 
      "/
          (
             (>|$)
             [^<]*
          )
          ($keyword)
      /x", 
      '$1<span class="keyword">$2</span>', 
      $body 
   );
}

disclaimer: even losse pols werk, maar 't gaat om 't idee
Vergeet trouwens niet, dat als je door html heen gaat zoeken je ook de keywords van te voren met htmlentities moet bewerken (en natuurlijk met preg_quote, zoals eerder gezegd).

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


Acties:
  • 0 Henk 'm!

  • Roa
  • Registratie: December 2002
  • Laatst online: 03-07-2024

Roa

Hoe zie je dat dan voor je? Dat je alle combinaties van Keyword kEyword keYword etc. gaat uitproberen? Erg efficient is dat niet ....
Ik was even veregeten dat je natuurlijk met keywords werkt! Dan is het inderdaad niet echt slim 8)7

Research is what I'm doing when I don't know what I'm doing.


Acties:
  • 0 Henk 'm!

  • Fles
  • Registratie: Augustus 2001
  • Laatst online: 06-04-2023
drm schreef op 12 maart 2003 @ 15:03:

[...]

Hoe zie je dat dan voor je? Dat je alle combinaties van Keyword kEyword keYword etc. gaat uitproberen? Erg efficient is dat niet ....



Als je de case wilt bewaren van de keywords in de tekst is het toch veel makkelijker om het met preg_replace te doen. Zorg dat je enkel woorden vervangt die niet in html-tags voorkomen (redelijk eenvoudige regex), zodat je niet een f***-up layout krijgt als ik op bijvoorbeeld 'div' of 'body' zoek... Ik weet overigens niet in hoeverre je in HTML zoekt, maar dat even daar gelaten...

Als je met preg_replace vervangt, kun je namelijk refereren aan het gedeelte wat je matcht met een zgn. backreference:

..

disclaimer: even losse pols werk, maar 't gaat om 't idee
Vergeet trouwens niet, dat als je door html heen gaat zoeken je ook de keywords van te voren met htmlentities moet bewerken (en natuurlijk met preg_quote, zoals eerder gezegd).
Ah perfect, ik wist niet dat het zo 'eenvoudig' was om uit te zoeken of het een tag was of niet.

Ik kan alleen in de nieuwe php manual die 'zooi' niet meer vinden voor preg_replace. Ik bedoel al die regels.
Ik kan dit natuurlijk wel zo overnemen, maar dan weet ik nog niet wat ik doe en hoe ik hem moet aanpassen :)

Oh en als ik em zo overneem dan werkt het niet. Heb dus echt ff die regels nodig dan pruts ik zelf wel ff.

edit:
Veel stront voorop trouwens :P

[ Voor 40% gewijzigd door Fles op 13-03-2003 01:20 ]


Acties:
  • 0 Henk 'm!

  • sjokki
  • Registratie: Juli 2002
  • Niet online
drm schreef op 12 March 2003 @ 15:03:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$keywords = array_unique ( $keywords );
foreach ( $keywords as $keyword ) {
   $keyword = preg_quote ( htmlentities ( $keyword ) );
   $body = preg_replace ( 
      "/
          (
             (>|$)
             [^<]*
          )
          ($keyword)
      /x", 
      '$1<span class="keyword">$2</span>', 
      $body 
   );
}
Dat werkt niet omdat er dan >'s in de tekst _moeten_ staan. Dit is ongeveer hetzelfde idee, maar werkt wel:
PHP:
1
2
3
4
5
6
7
8
9
10
   $body = preg_replace ( 
      "/
          $keyword
          (?!
             [^<]*>
          )
      /x", 
      '<span class="keyword">$0</span>', 
      $body 
   );
Verwijderd schreef op 11 March 2003 @ 01:03:
Als je een array in bijvoorbeeld strtr gebruikt, loopt hij maar een keer over de tekst heen, en vervangt niet wat je al vervangen hebt. Of dit ook in preg_replace mogelijk is weet ik niet.
Op deze manier wordt er maar 1 keer door de tekst gelopen:
PHP:
1
2
3
4
5
6
7
   $body = preg_replace ( 
      "/
          (?:keyword1|keyword2|keyword3)
      /x", 
      '<span class="keyword">$0</span>', 
      $body 
   );

Bij tests bleek deze methode twee tot tien keer keer zo snel als de bovenstaande.

De manual staat op http://be2.php.net/pcre

[ Voor 8% gewijzigd door sjokki op 13-03-2003 03:41 ]


Acties:
  • 0 Henk 'm!

  • Fles
  • Registratie: Augustus 2001
  • Laatst online: 06-04-2023
De tekst moet niet casesencetive zijn dus dan is dit het resultaat:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?
  function mark_words($searchstring, $text)
  {
    $keywords = str_replace(" ", "|", $searchstring);
    $text = preg_replace
    (  
      "/ 
        (?i:$keywords) 
      /x",  
      '<font style="background-color: gray">$0</font>',  
      $text  
    );
    return $text;
  }
?>


Btw, vrij pittig die pcre om er als beginner in te komen...

[ Voor 63% gewijzigd door Fles op 13-03-2003 12:04 ]


Acties:
  • 0 Henk 'm!

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

drm

f0pc0dert

Graveheart:
Btw, vrij pittig die pcre om er als beginner in te komen...
't lijkt moeilijker dan 't is. De beste manier om 't te leren is gewoon elke constructie goed doorlezen in de manual en dan met kleine patroontjes gaan uitproberen op strings, om vast te stellen dat je 't begrijpt.

Tenslotte zijn ingewikkeld uitziende regular expressions vaak niet meer dan een(onuitgelijnde*) verzameling van subpatroontjes ;)

* uitlijnen in regexes wordt imho veel te weinig gedaan

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

Pagina: 1