0

Hiya,

http://www.tizag.com/phpT/php-string-strpos.php

On the above link, it is stated:

PHP Code:
$numberedString = "1234567890"; // 10 numbers from 1 to 0

$fivePos = strpos($numberedString, "5");
echo "The position of 5 in our string was $fivePos";
Display:
The position of 5 in our string was 4
Notice that the position is 4, which may seem confusing at first, until you realize that PHP starts counting from 0.

The number 1 - Position 0 - No match
The number 2 - Position 1 - No match
The number 3 - Position 2 - No match
The number 4 - Position 3 - No match
The number 5 - Position 4 - Match
Although we only searched for a single character, you can use this function to search for a string with any number of characters. Also, it is important to note that this function will return the position of the start of the first match. So if we had searched the same string for "567890" we would again find a match and position 4 because that is where the match starts.

I do not understand the last part and so can someone show an example:
So if we had searched the same string for "567890" we would again find a match and position 4 because that is where the match starts.

3
Contributors
9
Replies
38
Views
3 Months
Discussion Span
Last Post by diafol
0

Oh, I now understand. It meant the string "567890" starts from position 4.
On previous example, it was searching for the single character 4's position. This time, it is searching where the string starts.

0

Ok. I understand that with strpos, you can only find the first match of a character or string but not any further than that if there were more than one match. And to fix this, I can use the incrementer to set the next starting point. Like so:

$numberedString = "1234567890123456789012345678901234567890";

$fivePos = strpos($numberedString, "5");
echo "The position of 5 in our string was $fivePos";
$fivePos2 = strpos($numberedString, "5", $fivePos + 1);
echo "<br />The position of the second 5 was $fivePos2";

So, naturally strpos has 2 parameters if you want to find the pos of only one match or the first match. Right ?
And, if you want to find all the matches' positions then you add the final matched position on the 3rd parameter. Right ?

2

You can also use a regular expression (regex), in PHP you can use regex with preg_* functions:

preg_match_all('/5/', $numberedString, $matches, PREG_OFFSET_CAPTURE);

The first argument is the pattern to search, the slashes are delimiters; the second argument is the subject to search, your string; the third argument is the array that will hold the results; the last argument is a constant to show the position of each match in the researched subject.

So, if you print it, you get:

print_r($matches);

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => 5
                    [1] => 4
                )

            [1] => Array
                (
                    [0] => 5
                    [1] => 14
                )

            [2] => Array
                (
                    [0] => 5
                    [1] => 24
                )

            [3] => Array
                (
                    [0] => 5
                    [1] => 34
                )

        )

)

About the docs: at the end of each function page, there is a list of other functions to consider as alternative. If you open php.net/strpos you get preg_match, which would return only $matches[0][0], from there you can reach preg_match_all. Once you get used, you just have to explore and test.

2

preg_match_all certainly easiest to use - but getting values out of the ensuing array can be a bit of a pain.

The examples on strpos also show a recursive UDF, which I've mangled a bit to serve my own purposes...

function multi_strpos($needle, $haystack, $offset = 0, &$results = array()) {                
    $offset = strpos($haystack, $needle, $offset);
    if($offset === false) {
        return $results;            
    } else {
        $results[] = $offset;
        return multi_strpos($needle, $haystack, ($offset + 1), $results);
    }
}

Usage:

multi_strpos('5', $string);

//note - my mangling - the change in order needle and haystack - although this follows the c classes in the underlying core, it's still a PITA.

This returns positions in a convenient array. I trialled both methods with microtime with finding "a" in 10 paragraphs of lorem ipsum and both returned times of "virtually zero", so there was no real difference for this type of usage. However, I like preg for its simplicity and not having to rely on UDFs.

Edited by diafol

2

Agree, preg results are painful. The following should ship the same output with preg_match_all():

$results = array_column($matches[0], 1);

However, I suspect it will add some overhead.

1

Yes the painful array functions. A loop for index 1 on each array of $matches[0] may be quicker. But preg itself very tidy. :)

0

Thanks guys for all the inputs. All this preg_match will become handy for me in the near future!

Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.