web-dev-qa-db-fra.com

PHP extraction de sous-chaîne. Récupère la chaîne avant le premier '/' ou la chaîne entière

J'essaie d'extraire une sous-chaîne. J'ai besoin d'aide pour le faire en PHP.

Voici quelques exemples de chaînes avec lesquelles je travaille et les résultats dont j'ai besoin:

home/cat1/subcat2 => home

test/cat2 => test

startpage => startpage

Je souhaite obtenir la chaîne jusqu'au premier /, mais si aucun / n'est présent, obtenez la chaîne entière.

J'ai essayé,

substr($mystring, 0, strpos($mystring, '/'))

Je pense que cela dit - récupère la position de / puis récupère la sous-chaîne de la position 0 à la position que.

Je ne sais pas comment gérer le cas où il n'y a pas de /, sans rendre la déclaration trop grande.

Existe-t-il un moyen de gérer également ce cas sans rendre l'instruction PHP trop complexe?

152
anon355079

Utilisez explode()

$arr = explode("/", $string, 2);
$first = $arr[0];

Dans ce cas, j'utilise le paramètre limit pour explode afin que php ne scanne pas plus la chaîne que nécessaire.

233
gnud

La solution la plus efficace est la fonction strtok :

strtok($mystring, '/')

Par exemple:

$mystring = 'home/cat1/subcat2/';
$first = strtok($mystring, '/');
echo $first; // home

et

$mystring = 'home';
$first = strtok($mystring, '/');
echo $first; // home
244
jmarceli
$first = explode("/", $string)[0];
95
AndyBrandy

Et ça :

substr($mystring.'/', 0, strpos($mystring, '/'))

Ajoutez simplement un '/' à la fin du mystère pour être sûr qu'il y en a au moins un;)

11
IRCF

Version à une ligne de la réponse acceptée:

$out=explode("/", $mystring, 2)[0];

Devrait fonctionner en php 5.4+

8
glyph

C'est probablement l'exemple le plus court qui m'est venu à l'esprit:

list($first) = explode("/", $mystring);

1) list() assignera automatiquement la chaîne jusqu'à "/" si un délimiteur est trouvé
2) si le délimiteur "/" n'est pas trouvé, la chaîne entière sera affectée

... et si vous êtes vraiment obsédé par les performances, vous pouvez ajouter un paramètre supplémentaire à exploser explode("/", $mystring, 2) qui limite le maximum d'éléments retournés.

8
pavlovich

Mieux vaut tard que jamais. php a une fonction prédéfinie pour cela. voici ce bon moyen.

strstr

si vous voulez obtenir la partie avant la correspondance, il suffit de définir before_needle (3ème paramètre) sur truehttp: // php. net/manual/en/function.strstr.php

function not_strtok($string, $delimiter)
{    
    $buffer = strstr($string, $delimiter, true);

    if (false === $buffer) {
        return $string;
    }

    return $buffer;
}

var_dump(
    not_strtok('st/art/page', '/')
);
6
aimme

La fonction strstr () dans PHP 5.3 doit remplir cette tâche. Le troisième paramètre doit toutefois être défini sur true.

Mais si vous n'utilisez pas la version 5.3, la fonction ci-dessous devrait fonctionner avec précision:

function strbstr( $str, $char, $start=0 ){
    if ( isset($str[ $start ]) && $str[$start]!=$char ){
        return $str[$start].strbstr( $str, $char, $start+1 );
    }
}

Je ne l'ai pas testé cependant, mais cela devrait fonctionner très bien .. Et c'est assez rapide aussi

5
Ronald

Vous pouvez essayer d'utiliser un regex comme ceci:

$s = preg_replace('|/.*$|', '', $s);

parfois, les expressions rationnelles sont plus lentes, donc si les performances sont un problème, assurez-vous de bien les comparer et utilisez une autre alternative avec des sous-chaînes si cela vous convient mieux.

2
t00ny

Vous pouvez créer une fonction d’aide pour s’occuper de cela:

/**
 * Return string before needle if it exists.
 *
 * @param string $str
 * @param mixed $needle
 * @return string
 */
function str_before($str, $needle)
{
    $pos = strpos($str, $needle);

    return ($pos !== false) ? substr($str, 0, $pos) : $str;
}

Voici un cas d'utilisation:

$sing = 'My name is Luka. I live on the second floor.';

echo str_before($sing, '.'); // My name is Luka
2
user5134807

Utiliser current sur explode faciliterait le processus.

 $str = current(explode("/", $str, 2));
2
user1518659
$string="kalion/home/public_html";

$newstring=( stristr($string,"/")==FALSE ) ? $string : substr($string,0,stripos($string,"/"));
0
kalion