How can I split a string in PHP at the nth occurrence of a needle?

后端 未结 12 1547
無奈伤痛
無奈伤痛 2020-11-29 08:25

There must be a fast and efficient way to split a (text) string at the "nth" occurrence of a needle, but I cannot find it. There is a fairly full set of functions

12条回答
  •  谎友^
    谎友^ (楼主)
    2020-11-29 08:48

    I really like Hamze GhaemPanah's answer for its brevity. However, there's a small bug in it.

    In the original code:

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

    $nth in the do while loop should be replaced with ($nth-1) as it will incorrectly iterate one extra time - setting the $pos to the position of the $nth+1 instance of the needle. Here's an example playground to demonstrate. If this link fails here is the code:

    $nth = 2;
    $string = "44 E conway ave west horse";
    $needle = " ";
    
    echo"======= ORIGINAL =======\n";
    
    $i = $pos = 0;
    do {
        $pos = strpos($string, $needle, $pos + 1);
    } while( $i++ < $nth);
    
    echo "position: $pos \n";
    echo substr($string, 0, $pos) . "\n\n";
    
    /*
        Outputs:
    
        ======= ORIGINAL =======
        position: 11
        44 E conway
    */
    
    echo"======= FIXED =======\n";
    
    $i = $pos = 0;
    do {
        $pos = strpos($string, $needle, $pos + 1);
    } while( $i++ < ($nth-1) );
    
    echo "position: $pos \n";
    echo substr($string, 0, $pos);
    
    /*
        Outputs:
    
        ======= FIXED =======
        position: 4
        44 E
    
    */
    

    That is, when searching for the position of the second instance of our needle, our loop iterates one extra time setting $pos to the position of our third instance of our needle. So, when we split the string on the second instance of our needle - as the OP asked - we get the incorrect substring.

提交回复
热议问题