4

I have a function that extracts the content between a $start and $end inside a $string

function get_string_between($string, $start, $end){
    $string = " ".$string;
    $ini = strpos($string,$start);
    if ($ini == 0) return "";
    $ini += strlen($start);
    $len = strpos($string,$end,$ini) - $ini;
    return substr($string,$ini,$len);
}

The problem with this is that it will only get me the first occurrence found in the string. Per example:

$text = "John has 13 oranges and Jane has 8 oranges";
$how_many_oranges = get_string_between($text,"has "," oranges");
echo $how_many_oranges; // echos "13"

I need it to find the last occurrence inside the string, so that $how_many_oranges = "8";

  • 2
    You could probably just swap out `strpos()` for [`strrpos()`](http://php.net/manual/function.strrpos.php) – Phil Jun 25 '18 at 01:47
  • I'm curious about the `$ini == 0` check; why are you doing that? If `$start` is at the very start of the string, `strpos()` will return `0`. Did you instead want to check for `$ini === false`, ie the string cannot be found? – Phil Jun 25 '18 at 01:55
  • Wouldn't that just be doing the same thing? ie return "" if not found? – gonna_take_sometime Jun 25 '18 at 02:07
  • 0 means found (at the start of the string) – Phil Jun 25 '18 at 02:40

5 Answers5

4

As mentioned in my comment, swap out strpos() for strrpos()

Find the numeric position of the last occurrence of needle in the haystack string.

Also, I believe you should change

if ($ini == 0)

to

if ($ini === false)

The former will match if $start is at the very beginning of $string. The latter will match if $start cannot be found at all.

Demo ~ https://eval.in/1027283

Phil
  • 157,677
  • 23
  • 242
  • 245
  • Thank you Phil. I've found that it's best to only replace the first strpos() to strrpos() -- replacing both introduces some issues in a number of scenarios. Per example, if $test = "John has 13 oranges and Jane has 8 oranges but they need more oranges", it will no longer give you "8" as result. Replacing only the first one fixes this. – gonna_take_sometime Jun 25 '18 at 10:26
1

What about using just PHP's built in function?!

strripos() – Finds the position of the last occurrence of a string inside another string. It is a Case-insensitive.

PHP Docs

SiL3NC3
  • 690
  • 6
  • 29
0

Try this:

function get_string_between($string, $start, $end){
    $p1 = explode($start,$str);
    for($i=1;$i<count($p1);$i++){
        $p2 = explode($end,$p1[$i]);
        $p[] = $p2[0];
    }
    return $p;
}

source: stackoverflow.com/a/45033158

Nader
  • 1,120
  • 1
  • 9
  • 22
0

I took the liberty to rewrote your code, to make it, IMHO, more readable and self-explanatory :)

I'd also recommend you to use the strrpos:

function getStringBetween($string, $start, $end) {
    $lastStartIndex = strrpos($string, $start);
    $lastEndIndex = strrpos($string, $end);

    $substringStartIndex = $lastStartIndex + strlen($start);
    $substringSize = $lastStartIndex - $lastEndIndex - 1;

    return substr($string, $substringStartIndex, $substringSize);
}

$text = "John has 13 oranges and Jane has 8 oranges";
$how_many_oranges = getStringBetween($text, "has", "oranges");
echo "'" . $how_many_oranges . "'"; // echos "' 8 '"
henrique
  • 1,072
  • 10
  • 17
0

This looks like a reasonable time to use regular expressions.

    function get_string_between($string, $start, $end) {
        $clean_start = preg_quote($start, '/');
        $clean_end = preg_quote($end, '/');
        $pattern = "/.*$clean_start (.*) $clean_end.*/U"; // U modifier => ungreedy
        $default_result = ''; // returned if no matches found
        $matches;
        preg_match_all($pattern, $string, $matches);
        return (count($matches[1]) > 0) ? end($matches[1]) : $default_result;
    }

echo get_string_between('John has 13 oranges and Jane has 8 oranges', 'has', 'oranges'); // 8
jstur
  • 659
  • 6
  • 12