PHP Find All Occurrences of a Substring in a String

PHP Find all occurrences of a substring in a string

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 />";
}

Get string between - Find all occurrences PHP

One possible approach:

function getContents($str, $startDelimiter, $endDelimiter) {
$contents = array();
$startDelimiterLength = strlen($startDelimiter);
$endDelimiterLength = strlen($endDelimiter);
$startFrom = $contentStart = $contentEnd = 0;
while (false !== ($contentStart = strpos($str, $startDelimiter, $startFrom))) {
$contentStart += $startDelimiterLength;
$contentEnd = strpos($str, $endDelimiter, $contentStart);
if (false === $contentEnd) {
break;
}
$contents[] = substr($str, $contentStart, $contentEnd - $contentStart);
$startFrom = $contentEnd + $endDelimiterLength;
}

return $contents;
}

Usage:

$sample = '<start>One<end>aaa<start>TwoTwo<end>Three<start>Four<end><start>Five<end>';
print_r( getContents($sample, '<start>', '<end>') );
/*
Array
(
[0] => One
[1] => TwoTwo
[2] => Four
[3] => Five
)
*/

Demo.

php find multiple occurence of string in string

Using a regular expression instead of strpos() is going to be you best bet. I've quickly put the following together which works with your example;

\{PID\s=([0-9]*)\}

You can see a working version here

Use of this in PHP would look like;

$re = '/\{PID\s=([0-9]*)\}/';
$str = 'some text {PID =340} {PID =357}';

preg_match_all($re, $str, $matches);

// Print the entire match result
print_r($matches);

Edit: Edited to return only the actual ID in the matched string. IMO - this is a better solution than the other 2 answers posted as it returns ID's of any length, and only returns ID's matched in the format you've provided.

I've also updated my working example.

PHP find positions of all occurrences of a particular word in a string

Just to demonstrate a non regexp alternative

$string = "It behooves us all to offer the prospectus for our inclusive syllabus";
$filterword = 'us';

$filtered = array_filter(
str_word_count($string,2),
function($word) use($filterword) {
return $word == $filterword;
}
);
var_dump($filtered);

where the keys of $filtered are the offset position

If you want case-insensitive, replace

return $word == $filterword;

with

return strtolower($word) == strtolower($filterword);

How to find all substrings of a string in PHP

Using the in-php-array-is-the-duct-tape-of-the-universe way :P

function get_all_substrings($input, $delim = '') {
$arr = explode($delim, $input);
$out = array();
for ($i = 0; $i < count($arr); $i++) {
for ($j = $i; $j < count($arr); $j++) {
$out[] = implode($delim, array_slice($arr, $i, $j - $i + 1));
}
}
return $out;
}

$subs = get_all_substrings("a b c", " ");
print_r($subs);

Get all occurrences of a string between two delimiters in PHP

Just use preg_match_all and keep things simple:

$input = "|foo| hello |foo| nothing here |foo| world |foo|";
preg_match_all("/\|foo\|\s*(.*?)\s*\|foo\|/", $input, $matches);
print_r($matches[1]);

This prints:

Array
(
[0] => hello
[1] => world
)

Find all occurrences of list of strings in array inside a sentence, and replace everything except the first letter with dashes

You may use this regex based approach using \G:

$str = 'hello, i think you are not intelligent, you are actually dumb and stupid.';
$list = array("dumb", "stupid", "brainless");

// use array_map to generate a regex of array for each word
$relist = array_map(function($s) {
return '/(?:\b(' . $s[0] . ')(?=' . substr($s, 1) . '\b)|(?!\A)\G)\pL/';
}, $list);

// call preg_replace using list of regex
echo preg_replace($relist, '$1-', $str) . "\n";

Code Demo

RegEx Demo

Output:

hello, i think you are not intelligent, you are actually d--- and s-----.

  • \G asserts position at the end of the previous match or the start of the string for the first match
  • (?!\A) is negative lookahead to make sure \G doesn't match at line start

Update:

As per your comments below you can use this different approach:

$str = 'word';
$relist = array_map(function($s) { return '/\b' . $s . '\b/'; }, $list);

echo preg_replace_callback($relist, function($m) {
return '<span class="bad">' . $m[0][0] . str_repeat('-', strlen($m[0])-1) . '</span>';
}, $str);

Output:

first <span class="bad">w---</span>

Find all substrings within a string with overlap

You're using echo to print the return value of preg_match_all. That is, you're displaying only the number of matches found. What you probably wanted to do was something like print_r($matches);, like this:

$haystack = "ACAAGACACATGCCACATTGTCC";
$needle = "ACA";
preg_match_all("/$needle/", $haystack, $matches);
print_r($matches);

Output:

Array
(
[0] => Array
(
[0] => ACA
[1] => ACA
[2] => ACA
)

)

Demo

If your real concern is that it counted ACACA only once, well, there are three things that need to be said about that:

  1. That's basically unavoidable with regex.
  2. You really shouldn't count this twice, as it's overlapping. It's not a true recurrence of the pattern.
  3. That said, if you want to count that twice, you could do so with something like this:

    echo preg_match_all("/(?=$needle)/", $haystack, $matches);

    Output:

    4

    Demo

php find a substring only if it's not part of another substring

You need a negative lookbehind regex:

/t(?!h(?:e|is))/i

See the regex demo

Pattern details:

  • t - a literal char t
  • (?!h(?:e|is)) - a negative lookbehind that checks if its pattern matches the string after the current location and failing the match (returning false) if the match occurs:

    • h - a literal h
    • (?:e|is) - either e or is (the (?:...|...) is a non-capturing group that does not keep submatches in the memory containing a | alternation operator)
  • /i - case insensitive modifier making the regex match in a case insensitive way.

Basically, this is a more efficient version of a t(?!he|his) regex (t not followed with he or his).

PHP demo:

$re = '/t(?!h(?:e|is))/i';

if (preg_match($re,'The cat and the dog are hungry'))
echo 'true';
else
echo 'false';


Related Topics



Leave a reply



Submit