PHP Find all occurrences of a substring in a string

PhpString

Php Problem Overview


I need to parse an HTML document and to find all occurrences of string asdf in it.

I currently have the HTML loaded into a string variable. I would just like the character position so I can loop through the list to return some data after the string.

The strpos function only returns the first occurrence. How about returning all of them?

Php Solutions


Solution 1 - Php

Without using regex, something like this should work for returning the string positions:

$html = "dddasdfdddasdffff";
$needle = "asdf";
$lastPos = 0;
$positions = array();

while (($lastPos = strpos($html, $needle, $lastPos))!== false) {
	$positions[] = $lastPos;
	$lastPos = $lastPos + strlen($needle);
}

// Displays 3 and 10
foreach ($positions as $value) {
	echo $value ."<br />";
}

Solution 2 - Php

You can call the strpos function repeatedly until a match is not found. You must specify the offset parameter.

Note: in the following example, the search continues from the next character instead of from the end of previous match. According to this function, aaaa contains three occurrences of the substring aa, not two.

function strpos_all($haystack, $needle) {
    $offset = 0;
    $allpos = array();
    while (($pos = strpos($haystack, $needle, $offset)) !== FALSE) {
        $offset   = $pos + 1;
        $allpos[] = $pos;
    }
    return $allpos;
}
print_r(strpos_all("aaa bbb aaa bbb aaa bbb", "aa"));

Output:

Array
(
    [0] => 0
    [1] => 1
    [2] => 8
    [3] => 9
    [4] => 16
    [5] => 17
)

Solution 3 - Php

Its better to use substr_count . Check out on php.net

Solution 4 - Php

Use preg_match_all to find all occurrences.

preg_match_all('/(\$[a-z]+)/i', $str, $matches);

For further reference check this link.

Solution 5 - Php

function getocurence($chaine,$rechercher)
        {
            $lastPos = 0;
            $positions = array();
            while (($lastPos = strpos($chaine, $rechercher, $lastPos))!== false)
            {
                $positions[] = $lastPos;
                $lastPos = $lastPos + strlen($rechercher);
            }
            return $positions;
        }

Solution 6 - Php

This can be done using strpos() function. The following code is implemented using for loop. This code is quite simple and pretty straight forward.

<?php

$str_test = "Hello World! welcome to php";

$count = 0;
$find = "o";
$positions = array();
for($i = 0; $i<strlen($str_test); $i++)
{
     $pos = strpos($str_test, $find, $count);
     if($pos == $count){
	       $positions[] = $pos;
     }
     $count++;
}
foreach ($positions as $value) {
    echo '<br/>' .  $value . "<br />";
}

?>

Solution 7 - Php

Salman A has a good answer, but remember to make your code multibyte-safe. To get correct positions with UTF-8, use mb_strpos instead of strpos:

function strpos_all($haystack, $needle) {
    $offset = 0;
    $allpos = array();
    while (($pos = mb_strpos($haystack, $needle, $offset)) !== FALSE) {
        $offset   = $pos + 1;
        $allpos[] = $pos;
    }
    return $allpos;
}
print_r(strpos_all("aaa bbb aaa bbb aaa bbb", "aa"));

Solution 8 - Php

Simple strpos_all() function.

function strpos_all($haystack, $needle_regex)
{
    preg_match_all('/' . $needle_regex . '/', $haystack, $matches, PREG_OFFSET_CAPTURE);
    return array_map(function ($v) {
        return $v[1];
    }, $matches[0]);
}

Usage: Simple string as needle.

$html = "dddasdfdddasdffff";
$needle = "asdf";

$all_positions = strpos_all($html, $needle);
var_dump($all_positions);

Output:

array(2) {
  [0]=>
  int(3)
  [1]=>
  int(10)
}

Or with regex as needle.

$html = "dddasdfdddasdffff";
$needle = "[d]{3}";

$all_positions = strpos_all($html, $needle);
var_dump($all_positions);

Output:

array(2) {
  [0]=>
  int(0)
  [1]=>
  int(7)
}

Solution 9 - Php

<?php
$mainString = "dddjmnpfdddjmnpffff";
$needle = "jmnp";
$lastPos = 0;
$positions = array();

while (($lastPos = strpos($html, $needle, $lastPos))!== false) {
    $positions[] = $lastPos;
    $lastPos = $lastPos + strlen($needle);
}

// Displays 3 and 10
foreach ($positions as $value) {
    echo $value ."<br />";
}
?>

Solution 10 - Php

Another solution is to use explode():

public static function allSubStrPos($str, $del)
{
    $searchArray = explode($del, $str);
    unset($searchArray[count($searchArray) - 1]);
    $positionsArray = [];
    $index = 0;
    foreach ($searchArray as $i => $s) {
        array_push($positionsArray, strlen($s) + $index);
        $index += strlen($s) + strlen($del);
    }
    return $positionsArray;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmuncherelliView Question on Stackoverflow
Solution 1 - PhpAdam PlocherView Answer on Stackoverflow
Solution 2 - PhpSalman AView Answer on Stackoverflow
Solution 3 - PhpNirmal RamView Answer on Stackoverflow
Solution 4 - PhpDeepuView Answer on Stackoverflow
Solution 5 - PhpRyodoView Answer on Stackoverflow
Solution 6 - PhpKachView Answer on Stackoverflow
Solution 7 - PhpmangroveView Answer on Stackoverflow
Solution 8 - PhpJaloView Answer on Stackoverflow
Solution 9 - PhpDr. NioView Answer on Stackoverflow
Solution 10 - PhpAmin.QarabaqiView Answer on Stackoverflow