开发者

Question about strpos: how to get 2nd occurrence of a string?

开发者 https://www.devze.com 2023-01-04 17:14 出处:网络
I understand that this function wi开发者_如何学Pythonll get the first occurrence of the string.

I understand that this function wi开发者_如何学Pythonll get the first occurrence of the string.

But what I want is the 2nd occurrence.

How to go about doing that?


I know this question is kind of old, but here's a function I wrote to get the Xth occurrence of a substring, which may be helpful for other people that have this issue and stumble over this thread.

/**
 * Find the position of the Xth occurrence of a substring in a string
 * @param $haystack
 * @param $needle
 * @param $number integer > 0
 * @return int
 */
function strposX($haystack, $needle, $number) {
    if ($number == 1) {
        return strpos($haystack, $needle);
    } elseif ($number > 1) {
        return strpos($haystack, $needle, strposX($haystack, $needle, $number - 1) + strlen($needle));
    } else {
        return error_log('Error: Value for parameter $number is out of range');
    }
}

Or a simplified version:

function strposX($haystack, $needle, $number = 0)
{
    return strpos($haystack, $needle,
        $number > 1 ?
        strposX($haystack, $needle, $number - 1) + strlen($needle) : 0
    );
}


You need to specify the offset for the start of the search as the optional third parameter and calculate it by starting the search directly after the first occurrence by adding the length of what you're searching for to the location you found it at.

$pos1 = strpos($haystack, $needle);
$pos2 = strpos($haystack, $needle, $pos1 + strlen($needle));


The recursive function from Smokey_Bud was slowing my script drastically down. Using a regular expression is much faster in this case (for finding any occurence):

function strposX($haystack, $needle, $number)
{
    // decode utf8 because of this behaviour: https://bugs.php.net/bug.php?id=37391
    preg_match_all("/$needle/", utf8_decode($haystack), $matches, PREG_OFFSET_CAPTURE);
    return $matches[0][$number-1][1];
}

// get position of second 'wide'
$pos = strposX('Hello wide wide world', 'wide', 2);


You can try this, though I haven't tested it out-

$pos = strpos($haystack, $needle, strpos($haystack, $needle)+strlen($needle));


To find second occurrence of the string you can use the strpos along with "offset" parameter, by adding previous offset to strpos.

$source = "Hello world, how you doing world...world ?";
$find = "world";
$offset = 0;
$findLength = strlen($find);
$occurrence = 0;

while (($offset = strpos($source, $find, $offset))!== false) {
    if ($occurrence ++) {
      break;
    }
    $offset += $findLength; 
}

echo $offset;

You can find all the occurrences by storing offset into an array

while (($offset = strpos($source, $find, $offset))!== false) {
  $occurrences[] = $offset;
  $offset += $findLength; 
}
var_export($occurrences);

Or can get a specific occurrence by matching $occurrence

//find 3rd occurrence
if ($occurrence ++ == 2) {
    break;
}


Simple is beautiful

function strposX($haystack, $needle, $n = 0)
{
    $offset = 0;

    for ($i = 0; $i < $n; $i++) {
        $pos = strpos($haystack, $needle, $offset);

        if ($pos !== false) {
            $offset = $pos + strlen($needle);
        } else {
            return false;
        }
    }

    return $offset;
}

$offset = strposX($result, "\n", $n);

if ($offset === false) {
    $offset = strlen($result) - 1;
}


Old question but how about using explode?

$corpus = "how many words are there in a dictionary? I'm not going to count them word by word...";
$looking_for = 'word';
$instance = 2;

$parts = explode($looking_for, $corpus, $instance + 1);
array_pop($parts);
$position = strlen(implode($looking_for, $parts));


Easily, just do it:

$i = $pos = 0;    
do {
        $pos = strpos( $string, $needle, $pos+1 );
} while( $i++ < $nth);

$nth for your situation is equal to 2.


function strpos_nth( $haystack, $needle, $occurrence ) 
{
    if ( filter_var( $occurrence, FILTER_VALIDATE_INT, [ "options" => ["min_range"=>1, "max_range"=>strlen($haystack)] ] ) === false)
        return false ;

    $loop     = 0;
    $position = -1;
    while ( $position!==false && ++$loop<=$occurrence ) 
        $position = strpos( $haystack, $needle, ++$position );

    return $position;
}

https://onlinephp.io/c/7d44a


just worked for me to find if are 2 or more occurrence of a char, then by strlen them i found that exist 2 occurrence ex ( i dont use $matches at all):

$string = '1234|6|#red';

if(strlen(preg_match_all('/|/', $string,$matches, PREG_OFFSET_CAPTURE)) ==2){

echo 'i have 2 occurence of char: |';

    }


Old question, but if someone's looking for a way to find occurrences from the END of the string (for example 3rd occurrence of dot from the end) the following function works (didn't want to use oncodes function not to mess with encoding)

$str = "NooooYesYesNo";

function find_occurence_from_end($haystack, $needle, $num) {

    for ($i=1; $i <=$num ; $i++) {

        # first loop return position of needle
        if($i == 1) {
            $pos = strrpos($haystack, $needle);
        }

        # subsequent loops trim haystack to pos and return needle's new position
        if($i != 1) {

            $haystack = substr($haystack, 0, $pos);
            $pos = strrpos($haystack, $needle);

        }

    }

    return $pos;

}

$pos = find_occurence_from_end($str, "Yes", 2);

// 5

It's super simple. Basically each time it finds an occurrence of your needle it "trims" the string to that position. So it keeps on trimming it while returning the latest position each time.


function substr_Index( $str, $nth ){
    $str2 = '';
    $posTotal = 0;
    for($i=0; $i < $nth; $i++){

        if($str2 != ''){
            $str = $str2;
        }

        $pos   = strpos($str, ':');
        $str2  = substr($str, $pos+1);
        $posTotal += $pos+1;

    }
    return $posTotal-1;
}


echo substr($mystring, substr_Index( $mystring , 2) );

Function returns position of nth delimiter.

Second parameter of substr_Index must be bigger than 0;

To find second occourance use substr_Index( $mystring , 2)


//Finds nth occourance of string after position of given needle.
//Pass $needle argument as empty string [''] if you want to find from start
//Pass $needle argument as Int to search string from this position

function substr_Index( $string, $needle, $delimiter, $nth ){
    $str2 = '';
    $posf = strpos($string, $needle);
    if($posf !== false){
        $string   = substr($string, $posf);
        $posTotal = $posf;      
    }else{
        $posTotal = 0;
    }
    
    if( is_int($needle) ){
        $posTotal = $needle;
    }

    for($i=0; $i < $nth; $i++){
        
        if($str2 != ''){
            $string = $str2;
        }
             
        $pos   = strpos($string, $delimiter);
        $str2  = substr($string, $pos + 1);
        $posTotal += $pos+1;
        
    }
    return $posTotal-1;
}
               
//example (returns part of given string from second [:] next from first [#]  )
$str_ = '..:....:..:....#,61185:9789756130346:0000000:369615:97860510:61436=0000000323636';

echo substr($str_, substr_Index( $str_, '#' , ':', 2) );


Please check the following code ... it works pretty fine for me.

<?php
    function f_srch ($s1, $par) {
        echo 'Searching for [' . $par . '] in [' . $s1 . ']<br>';
        $k = 0; //while loop
        $i = 0; // counter

        while ($k >= 0) {
            $pos = strpos($s1, $par, $k);
            if ($pos === false) {
                $k=-1;
                echo 'Letter not found'.'<br>';
            } else {
                if ($pos == $k) { 
                    echo 'The position of the letter is '.$pos.'<br>'; 
                    $i++;
                }
                $k++;
            } 
        }
        echo 'The letter was found ' . $i . ' time(s).'.'<br>'; 
    }
    f_srch('i am searching for a letter in this sentence','t');
?>


http://php.net/strpos

$newstring = 'abcdef abcdef';
$pos = strpos($newstring, 'a', 1);  // $pos = 7, not 0
0

精彩评论

暂无评论...
验证码 换一张
取 消