160 votes

PHP - itérer sur les caractères d'une chaîne de caractères

Existe-t-il un moyen agréable d'itérer sur les caractères d'une chaîne de caractères ? J'aimerais pouvoir faire foreach , array_map , array_walk , array_filter etc. sur les caractères d'une chaîne de caractères.

Le casting/jonglage de type ne m'a mené nulle part (mettre la chaîne entière comme un élément du tableau), et la meilleure solution que j'ai trouvée est simplement d'utiliser une boucle for pour construire le tableau. J'ai l'impression qu'il devrait y avoir quelque chose de mieux. Je veux dire, si vous pouvez l'indexer, ne devriez-vous pas être capable d'itérer également ?

C'est le meilleur que j'ai.

function stringToArray($s)
{
    $r = array();
    for($i=0; $i<strlen($s); $i++) 
         $r[$i] = $s[$i];
    return $r;
}

$s1 = "textasstringwoohoo";
$arr = stringToArray($s1); //$arr now has character array

$ascval = array_map('ord', $arr);  //so i can do stuff like this
$foreach ($arr as $curChar) {....}
$evenAsciiOnly = array_filter( function($x) {return ord($x) % 2 === 0;}, $arr);

Est-ce qu'il y a soit :

A) Un moyen de rendre la chaîne de caractères itérable
B) Une meilleure façon de construire le tableau de caractères à partir de la chaîne de caractères (et si oui, comment faire dans l'autre sens ?)

J'ai l'impression de rater quelque chose d'évident ici.

0 votes

Peut-être devriez-vous en dire plus sur ce que vous essayez d'accomplir... il semble qu'il y ait un meilleur moyen de le faire en utilisant les opérations normales sur les chaînes de caractères.

1 votes

Je n'ai pas de réel objectif ici. juste une curiosité avec laquelle je jouais. il me semblait bizarre que même si vous pouvez indexer sur des chaînes de caractères, vous ne pouvez pas itérer. je n'arrivais même pas à penser à des exemples d'utilisation significatifs, mais j'aimerais quand même savoir s'il y a un moyen d'itérer sur les caractères des chaînes de caractères sans construire un tableau de caractères explicitement.

0 votes

C'est un bon point cependant, évidemment mes exemples sont assez superficiels. c'est-à-dire - principalement tout ce que vous feriez avec array_filter dans ce sens, il serait préférable d'utiliser les fonctions string ou reg-ex.

230voto

SeaBrightSystems Points 416

Étape 1 : convertir la chaîne en un tableau en utilisant la fonction str_split fonction

$array = str_split($your_string);

Étape 2 : boucle à travers le tableau nouvellement créé

foreach ($array as $char) {
 echo $char;
}

Vous pouvez consulter la documentation de PHP pour plus d'informations : str_split

0 votes

Hah wow. yep c'est ça. et bien sûr implode peut faire l'inverse. Je vais accepter cela bientôt, sauf si quelqu'un peut montrer un moyen de faire l'itération directement sur le dard.

0 votes

@jon_darkstar Je ne connais pas votre application, mais notez que chaque entrée d'un tableau a une surcharge significative (4bytes IIRC). Si vous passez outre, c'est "plutôt" beaucoup plus : nikic.github.com/2011/12/12/

2 votes

str_split() will split into bytes, rather than characters when dealing with a multi-byte encoded string. - Donc str_split ne peut pas fonctionner avec Unicode

120voto

Owen Points 1319

Iterate string :

for ($i = 0; $i < strlen($str); $i++){
    echo $str[$i];
}

21voto

JohnM2 Points 3543

Si vos chaînes de caractères sont en Unicode, vous devriez utiliser preg_split avec /u modificateur

D'après les commentaires dans la documentation de php :

function mb_str_split( $string ) { 
    # Split at all position not after the start: ^ 
    # and not before the end: $ 
    return preg_split('/(?<!^)(?!$)/u', $string ); 
}

3 votes

Pour les chaînes de caractères à plusieurs octets, mb_split est plus fiable.

0 votes

Citation requise @Lux

0 votes

@mickmackusa Cela fait quelques années (et de nos jours, vous devriez probablement utiliser la bibliothèque stdlib mb_str_split si vous êtes en PHP7.4), et je ne me souviens pas vraiment de ce que je voulais dire, mais je pense que preg_split avec le paramètre /.../u est uniquement UTF-8 (PAS 'Unicode', comme le dit le PO) alors que mb_split permet un encodage arbitraire (en plus, mb_split est explicitement conçu pour le découpage de regex sur des chaînes multi-octets, il peut donc avoir quelques optimisations supplémentaires et autres ? et en général, puisqu'il est conçu à cet effet, je suppose par défaut qu'il est plus fiable et/ou complet qu'une extension /u PCRE)

14voto

Moritur Points 538

Vous pouvez également accéder à $s1 comme à un tableau, si vous n'avez besoin que d'y accéder :

$s1 = "hello world";
echo $s1[0]; // -> h

8voto

TechJS Points 1628

Pour ceux qui cherchent le moyen le plus rapide d'itérer sur des chaînes de caractères en php, j'ai préparé un test de référence.
La première méthode dans laquelle vous accédez directement aux caractères de la chaîne de caractères en spécifiant sa position entre parenthèses et en traitant la chaîne comme un tableau :

$string = "a sample string for testing";
$char = $string[4] // equals to m

Je pensais moi-même que cette dernière méthode était la plus rapide, mais je me trompais.
Comme pour la deuxième méthode (qui est utilisée dans la réponse acceptée) :

$string = "a sample string for testing";
$string = str_split($string);
$char = $string[4] // equals to m

Cette méthode sera plus rapide, car nous utilisons un fichier réel et ne pas supposer qu'il s'agit d'un tableau.

En appelant la dernière ligne de chacune des méthodes ci-dessus pour 1000000 temps conduisent à ces résultats d'analyse comparative :

Utilisation de la chaîne [i]
0.24960017204285 Seconds

Utilisation de str_split
0.18720006942749 Seconds

Ce qui signifie que la seconde méthode est bien plus rapide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X