web-dev-qa-db-fra.com

PHP - itérer sur des caractères de chaîne

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

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

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 itérable
B) Une meilleure façon de construire le tableau de caractères à partir de la chaîne (et si oui, que diriez-vous de l’autre direction?)

Je sens que je manque quelque chose d’évident ici.

88
jon_darkstar

Étape 1: convertissez la chaîne en un tableau à l'aide de la fonction _str_split_

$array = str_split($your_string);

Étape 2: parcourir le tableau nouvellement créé

_foreach ($array as $char) {
 echo $char;
}
_

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

144
SeaBrightSystems

Itérer la chaîne:

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

Si vos chaînes sont en Unicode, vous devez utiliser preg_split avec /u modificateur. 

De commentaires dans la documentation php:

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

Vous pouvez aussi simplement accéder à $ s1 comme un tableau, si vous devez seulement y accéder:

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

Développé à partir de la réponse de @SeaBrightSystems, vous pouvez essayer ceci:

$s1 = "textasstringwoohoo";
$arr = str_split($s1); //$arr now has character array
5
Dairy Window

Pour ceux qui recherchent le moyen le plus rapide de parcourir des chaînes en php, Ive a préparé un test de référence.
La première méthode dans laquelle vous accédez directement aux caractères de chaîne en spécifiant sa position entre parenthèses et en traitant chaîne comme un tableau

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

J'ai moi-même pensé que la dernière méthode était la plus rapide, mais je me suis trompé.
Comme avec 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 va être plus rapide car nous utilisons un tableau real et ne supposons pas qu’il s’agisse d’un tableau. 

L'appel de la dernière ligne de chacune des méthodes ci-dessus pour 1000000 fois conduit aux résultats suivants: 

Utilisation de la chaîne [i]
0.24960017204285 Seconds 

Utilisation de str_split
0.18720006942749 Seconds

Ce qui signifie que la deuxième méthode est beaucoup plus rapide.

5
TechJS

Hmm ... Il n'y a pas besoin de compliquer les choses. Les bases fonctionnent toujours très bien. 

    $string = 'abcdef';
    $len = strlen( $string );
    $x = 0;

Direction vers l'avant:  

while ( $len > $x ) echo $string[ $x++ ];

Sorties: abcdef

Direction inverse:

while ( $len ) echo $string[ --$len ];

Sorties: fedcba

0
Ash

La plupart des réponses ont oublié les caractères non anglais !!!

strlen compte BYTES, pas de caractères, c’est pourquoi il en est ainsi. Ses fonctions sœurs fonctionnent parfaitement avec les caractères anglais, car les caractères anglais sont stockés dans un octet à la fois en codages UTF-8 et ASCII. besoin d'utiliser les fonctions de chaînes multi-octetsmb_*

Cela fonctionnera avec n’importe quel caractère encodé en UTF-8

$string = "abcdأبتث";

$charsCount = mb_strlen($string, 'UTF-8');
for($i = 0; $i < $charsCount; $i++){
    $char = mb_substr($string, $i, 1, 'UTF-8');
    var_dump($char);
}

Ceci sorties

string(1) "a"
string(1) "b"
string(1) "c"
string(1) "d"
string(2) "أ"
string(2) "ب"
string(2) "ت"
string(2) "ث"
0
Accountant م
// Unicode Codepoint Escape Syntax in PHP 7.0
$str = "cat!\u{1F431}";

// IIFE (Immediately Invoked Function Expression) in PHP 7.0
$gen = (function(string $str) {
    for ($i = 0, $len = mb_strlen($str); $i < $len; ++$i) {
        yield mb_substr($str, $i, 1);
    }
})($str);

var_dump(
    true === $gen instanceof Traversable,
    // PHP 7.1
    true === is_iterable($gen)
);

foreach ($gen as $char) {
    echo $char, PHP_EOL;
}
0
masakielastic