James Skidmore
James Skidmore

Reputation: 50338

How to find the second-to-last occurrence of a character within a string?

If possible, using only standard PHP functions like substr(), strrpos(), strpos(), etc.

Upvotes: 16

Views: 15453

Answers (6)

will
will

Reputation: 149

You can can use two lots of strrpos with a negative offset to do the trick:

$str = 'foo fighters fight foo';    
$p0 = strrpos($str,' '); // get position o last space
$os = -strlen($str)+$p0-1; // negative search offset
$p1 = strrpos($str,' ',$os); // position of the second last space
echo '"'.substr($str,$p1).'"'; // result

Upvotes: 0

brian-brazil
brian-brazil

Reputation: 34172

First, find the last position:

$last = strrpos($haystack, $needle);
if ($last === false) {
  return false;
}

From there, find the 2nd last:

$next_to_last = strrpos($haystack, $needle, $last - strlen($haystack) - 1);

Upvotes: 29

Matthew Flaschen
Matthew Flaschen

Reputation: 285047

General solution for any number of backwards steps:

function strrpos_count($haystack, $needle, $count)
{
    if($count <= 0)
        return false;

    $len = strlen($haystack);
    $pos = $len;

    for($i = 0; $i < $count && $pos; $i++)
        $pos = strrpos($haystack, $needle, $pos - $len - 1);

    return $pos;
}

Upvotes: 10

Martin Tilsted
Martin Tilsted

Reputation: 709

I don't think this can be done with strrpos because the position start does not work in the way you would expect.

There is afaik not any obvious way, but this function should do it. (Not really tested, but I think it work).

    /** Return the position of the second last needle in haystack or false if nothing is found. I really hate functions with return types that depend on their input, but this function is made to look like the similary php functions (strpos, strrpos and so on) */

// Needle must be a char. If you want it to be a string instead, just substr
// length of needle instead of 1 in this example.
    function findSecondLastChar($needle,$haystack) {
      $found=0;
      for($pos=strlen($haystack)-1;$pos>=0;$pos--) {
        if(substr($haystack,$pos,1)==$needle) {
          if($found++ == 1)
            return $pos;
        }
      }
       // If we reach this, nothing were found
       return false;
    }

Upvotes: 0

ilya n.
ilya n.

Reputation: 18826

Search for a regexp (plz correct me if I'm wrong, and how to write it in PHP):

    r'x[^x]*x[^x]*$'.replace('x',your_char)

Upvotes: 0

Gumbo
Gumbo

Reputation: 655755

With strpos:

$pos = -1; $last = null; $secondLast = null;
while (($pos = strpos($haystack, $needle, $pos+1)) !== false) {
    $secondLast = $last;
    $last = $pos;
}
if (!is_null($secondLast)) {
    echo 'second last occured on '.$secondLast;
}

Upvotes: 1

Related Questions