Posities van alle substring in een string bepalen

Door Mitch X, 23 jaar geleden, 5.170x bekeken

Een duidelijke uitleg bij het zelfstandig verbeteren/aanpassen van de standaardfunctie strpos()

Gesponsorde koppelingen

Inhoudsopgave

  1. Intro
  2. Theorie
  3. Uitwerking

 

Er zijn 12 reacties op 'Posities van alle substring in een string bepalen'

PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Jan Koehoorn
Jan Koehoorn
23 jaar geleden
 
0 +1 -0 -1
Goede tut! Klein zpelvaudju op pagina 3: het is niet "ten alle tijden", maar "te allen tijde".
- SanThe -
- SanThe -
23 jaar geleden
 
0 +1 -0 -1
Leuke functie. Erg duidelijke uitleg.
Robert Deiman
Robert Deiman
23 jaar geleden
 
0 +1 -0 -1
Leuke tut, kan nog wel eens van pas komen.
Mitch X
Mitch X
23 jaar geleden
 
0 +1 -0 -1
Zpelvaudju is weg ;)
Willem vp
Willem vp
23 jaar geleden
 
0 +1 -0 -1
Notice: Uninitialized string offset: 24 in /home/willem/public_html/test.php on line 21

Dat is de regel: for( $i = 0; $Haystack{$i}; $i++ )

Je hoogt wel zo mooi je $i op, maar vergeet ondertussen te testen of je niet voorbij het eind van de string loopt ;-)

Overigens is het gedeelte if(count($Matches)) etc niet nodig. Aangezien je aan het begin $Matches initialiseert als een lege array, kun je gewoon $Matches teruggeven.
Willem vp
Willem vp
23 jaar geleden
 
0 +1 -0 -1
Ik ben even zo vrij geweest om de routine wat compacter te maken. Zonde om niet gewoon gebruik te maken van de (geoptimaliseerde) strpos()-functie.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?
function wvpStrpos($haystack,$needle)
{

   $lucifers = array();

   # Vanaf PHP 5.0 is de strtolower() niet meer nodig en kun je stripos() gebruiken
   $needle = strtolower($needle);
   $haystack = strtolower($haystack);

   $offset = 0;
   while (($pos = strpos($haystack,$needle,$offset)) !== false)
   {

      $lucifers[] = $pos;
      $offset = $pos+1;          # Zoek in de rest van de haystack
   }

   return $lucifers;
}

?>
Mitch X
Mitch X
23 jaar geleden
 
0 +1 -0 -1
Dat array ding was ik inderdaad ook al achter gekomen.
Quote:
Dat is de regel: for( $i = 0; $Haystack{$i}; $i++ )

Je hoogt wel zo mooi je $i op, maar vergeet ondertussen te testen of je niet voorbij het eind van de string loopt ;-)

En wat denk je dat $Haystack{$i} doet ;)
( Zou dat niet werken heb je een infinite loop... )
Die checkt daar dus op, hier dan ook geen errors op PHP5.
Willem vp
Willem vp
23 jaar geleden
 
0 +1 -0 -1
Stel dat je een haystack van 10 tekens hebt. Die loopt dan van $haystack{0} t/m $haystack{9}. Jouw for-loop eindigt bij de test voor $haystack{10}. Dat is echter officieel geen element meer van de string en dus mag je er niet meer op testen.

Het codewoord hier is: "buffer overflow", een van de meest voorkomende redenen van security exploits. Jouw PHP geeft er geen error op, de mijne (4.4.0) wel. Een nog oudere PHP merkt het misschien niet eens en gaat vrolijk door. In het kader van veilig en defensief programmeren is het dan ook een constructie die absoluut af te raden is.

Wanneer je van plan bent om later ook nog met andere talen te gaan werken is het trouwens zeer zeker aan te raden dit soort constructies niet aan te leren. Niet iedere taal is zo vergevingsgezind als PHP ;-)
Willem vp
Willem vp
23 jaar geleden
 
0 +1 -0 -1
Trouwens nog een opmerking: in de tweede for-loop roep je strlen($Needle) aan. Als je nu een hele grote haystack en een hele lange needle hebt, krijg je dus een heleboel aanroepen van strlen(). Is best nadelig voor de performance.

Aangezien de needle niet verandert, kun je dus v??r de 1e for-loop een variabele setten met de waarde van strlen($Needle) en in je for-loop die waarde gebruiken. Dat zal de performance stukken verbeteren.
Mitch X
Mitch X
23 jaar geleden
 
0 +1 -0 -1
Quote:
Wanneer je van plan bent om later ook nog met andere talen te gaan werken is het trouwens zeer zeker aan te raden dit soort constructies niet aan te leren. Niet iedere taal is zo vergevingsgezind als PHP ;-)

In een taal als C++ is dit zelfs een constructie die ik in een aantal boeken ben tegengekomen.
W?l aan te raden dus.
Hoewel het bij C++ iets netters is doordat daar echt een nulterminator is.

Je andere kritiekpunt is wel waar, niet eens aan gedacht :$
Willem vp
Willem vp
23 jaar geleden
 
0 +1 -0 -1
Het feit dat het in een boek staat wil nog niet zeggen dat het verstandig is ;-) In een boek als "Safer C" zul je deze methode dan ook zeker niet tegenkomen. In C of C++ wordt elke string in principe be?indigd met een null-karakter, maar je wilt niet weten hoeveel programmeurs een string van bijvoorbeeld 10 karakters defini?ren en daar 10 karakters in zetten. Zo'n string heeft dan geen nul-karakter en als je dan toch je string-index gebruikt als conditie in een for-loop, loop je alsnog buiten je string.

Het feit dat PHP een notice geeft wil zeggen dat het ook in PHP geen veilige programmeermethode is. Gewoon niet doen dus, want je introduceert er een potentieel beveiligingsprobleem mee. Het is veel veiliger om als conditie $i < $Length te gebruiken. Dat is bovendien sneller, omdat PHP niet iedere keer $Haystack hoeft te dereferencen.
PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Nick
Nick
23 jaar geleden
 
0 +1 -0 -1
Willem vp heeft gelijk, boeken met zulk groot aantal concurrentie zijn meestal door geld willende wolfen geschreven en gooien vaak niet zuivere scripts erin

Om te reageren heb je een account nodig en je moet ingelogd zijn.

Inhoudsopgave

  1. Intro
  2. Theorie
  3. Uitwerking

Labels

  • Geen tags toegevoegd.

PHP tutorial opties

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.