web-dev-qa-db-fra.com

Question sur les strpos. Comment obtenir la 2ème occurrence de la chaîne?

Je comprends que cette fonction obtiendra la première occurrence de la chaîne.

Mais ce que je veux, c'est la 2ème occurrence.

Comment s'y prendre?

43
vfvg

Vous devez spécifier le décalage pour le début de la recherche en tant que troisième paramètre facultatif et le calculer en démarrant la recherche directement après la première occurrence en ajoutant la longueur de ce que vous recherchez à l'emplacement où vous l'avez trouvée.

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

Je sais que cette question est un peu ancienne, mais voici une fonction que j'ai écrite pour obtenir la Xème occurrence d'une sous-chaîne, qui peut être utile pour les autres personnes qui ont ce problème et qui trébuchent sur ce fil.

/**
 * 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');
    }
}
45
TheKidsWantDjent

La fonction récursive de Smokey_Bud ralentissait mon script de manière drastique. L'utilisation d'une expression régulière est beaucoup plus rapide dans ce cas (pour rechercher une occurrence):

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);
10
oncode

Pour trouver la deuxième occurrence de la chaîne, vous pouvez utiliser le paramètre strpos avec le paramètre "offset" en ajoutant le décalage précédent à 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;

Vous pouvez trouver toutes les occurrences en stockant l'offset dans un tableau

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

Ou peut obtenir une occurrence spécifique en faisant correspondre $ occurrence 

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

Vous pouvez essayer ceci, bien que je ne l'aie pas testé

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

Le simple est beau

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;
}
2
tom10271

Ancienne question, mais si quelqu'un cherche un moyen de trouver des occurrences à partir de la fin de la chaîne (par exemple, la 3ème occurrence du point à partir de la fin), la fonction suivante fonctionne (ne souhaitait pas utiliser la fonction oncodes pour ne pas gâcher le codage)

$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

C'est super simple. En gros, chaque fois qu’il trouve une occurrence de votre aiguille, il "coupe" la corde à cette position. Donc, il continue à le rogner tout en retournant la dernière position à chaque fois.

0
Robert Sinclair

je viens de travailler pour moi pour savoir s’il ya 2 occurrences ou plus d’un caractère, puis, par strlen, j’ai trouvé qu'il existe 2 occurrences ex (je n’utilise pas $ correspond du tout):

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

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

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

    }
0
Dan