Tutorials

Posities van alle substring in een string bepalen

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

Pagina 1

Intro

De PHP standaardlib is zeer uitgebreid, en voldoet in de meeste gevallen.
Helaas kon ik geen functie vinden die doet wat strpos() doet ( de index van je substring teruggeven maar slechts voor de eerste keer dat hij voorkomt ) die meerdere indeces returnt als er meerdere zijn!

Dat zul je dan zelf op moeten lossen, en het leek me een goed plan om deze oplossing als voorbeeld te nemen voor het uitbreiden van de PHPlib.

Stroop je mouwen op en klik met me mee naar de volgende pagina!
Pagina 2

Theorie

Om onze functie te kunnen beginnen moeten we weten hoe strpos() doet wat hij doet.
Dat is natuurlijk niet zo moeilijk te bedenken, want hoe doe je dat zelf?

Juist!
Je zoekt in de hele string naar een overeenkomst met hetgeen je zoekt, als je "ik" zoekt zoek je dus een woord dat begint met een "i" met daaropvolgend een "k".

Als je even met me meetelt hebben we dus 2 loopjes nodig, 1 om door de hele string te fietsen, een tweede om een match te vinden.
En dan moeten we vooral niet stoppen bij de eerste match maar netjes doorzoeken!

Komen we bij het laatste deel van de theorie, hoe loop ik door een string?!one!1!
Een string zijn gewoon een x aantal karakters, en die hebben allemaal een eigen index.
In een taal als bijv. C++ zijn het echte arrays, dus met [index], php gebruik {index}.

Kun je al zelf een oplossing bedenken?
Mijne staat in ieder geval op de volgende pagina :)
Pagina 3

Uitwerking

<?php
# Custom strpos
function myStrpos( $Haystack, $Needle )
{
# Matches array
$Matches = array( );

# Lowercase both $Haystack & $Needle
$Needle = strtolower( $Needle );
$Haystack = strtolower( $Haystack );

# Lengt needle
$Length = strlen( $Needle ) - 1;

# Loop through string
for( $i = 0; $Haystack{$i}; $i++ )
{
# Save start position
$Start = $i;

# (*1)
for( $j = 0; $Haystack{$i+$j} == $Needle{$j}; $j++ )
{
# Match has been found if $j reaches strlen-1
if( $Length == $j )
{
# Save start pos
$Matches[] = $Start;
break;
}
}
}

# Return array
return $Matches;
}
?>

Je ziet 2 sterretjes in de comments, hieronder de verklaring ;)
*1 Zoals je ziet hoeft een for() loop niet altijd een $i<getal te hebben, je kunt alle true/false expressies gebruiken die je wilt, en dat biedt uitkomst in onze functie.

*2 Je vraagt je vast af waarom ik een lege array teruggeef als er geen matches zijn. Dat is om de doodsimpele reden dat een nette functie maar 1 return type mag hebben. Er wordt nu dus te allen tijde een array teruggegeven.
if( count( $array ) > 0 ) zou je bijv. als "check" op matches kunnen gebruiken.

Succes ermee, en post hier je eigen PHPlib verbeteringen!

Reacties

0
Nog geen reacties.