2011-01-05 12 views
69

C'è un modo piacevole per iterare sui caratteri di una stringa? Mi piacerebbe essere in grado di fare foreach, array_map, array_walk, array_filter ecc. Sui caratteri di una stringa.PHP - iterare su caratteri stringa

Il cast di tipo/juggling non mi ha portato ovunque (metto l'intera stringa come un elemento dell'array) e la soluzione migliore che ho trovato è semplicemente usare un ciclo for per costruire l'array. Sembra che ci dovrebbe essere qualcosa di meglio. Voglio dire, se puoi indicizzare su di esso non dovresti essere in grado di ripetere anche tu?

Questa è la migliore che ho

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

C'è uno:

A) Un modo per rendere la stringa iterabile
B) Un modo migliore per costruire l'array di caratteri dal stringa (e se sì, che dire circa l'altra direzione?)

Mi sento come mi manca qualcosa di ovvio qui.

+0

Forse si dovrebbe dire di più su che si sta cercando di realizzare ... sembra che ci potrebbe essere un modo migliore per farlo utilizzando le normali operazioni sulle stringhe. –

+0

non hanno un vero obiettivo qui. solo una curiosità con cui stavo giocando. sembrava strano che anche se puoi indicizzare le stringhe non puoi iterare. non riuscivo nemmeno a pensare a usi di esempi significativi, ma mi piacerebbe comunque sapere se c'è un modo per iterare sui personaggi delle stringhe senza costruire un array di caratteri esplicitamente –

+0

ma, ovviamente, i miei esempi sono piuttosto superficiali. vale a dire - per lo più tutto ciò che faresti con 'array_filter' in questo senso potrebbe essere fatto meglio con le funzioni string o reg-ex –

risposta

89

Fase 1: convertire la stringa in un array usando la funzione

str_split

$array = str_split($your_string);

Fase 2: scorrere l'array di nuova creazione

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

È possibile controllare il Documenti PHP per ulteriori informazioni: str_split

+0

hah wow. sì è così. e naturalmente implode può fare l'altra direzione. Lo accetterò presto a meno che qualcuno non mostri un modo per eseguire l'iterazione direttamente sulla puntura –

+0

@jon_darkstar Non conosco la tua applicazione, ma prendo atto che ogni voce in una matrice ha un overhead significativo (4bytes IIRC). Salta questo, è "abbastanza" molto di più: http://nikic.github.com/2011/12/12/How-big-are-PHP-arrays-really-Hint-BIG.html –

19

Se le stringhe sono in Unicode si dovrebbe usare preg_split con /u modificatore

Da commenti nella documentazione di PHP:

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

Per stringhe multibyte, ' mb_split' è più affidabile. – Xenon

5

ampliato da @SeaBrightSystems rispondere, si potrebbe provare questo:

$s1 = "textasstringwoohoo"; 
$arr = str_split($s1); //$arr now has character array 
+0

Downvoted perché questa risposta non aggiunge valore. La risposta @SeaBrightSystems contiene già tutte le informazioni necessarie e un collegamento alla documentazione. –

+0

Non sono d'accordo, questa risposta aggiunge valore, fornisce un esempio funzionante di come str_split potrebbe funzionare in un'applicazione PHP. @SeaBrightSystems si limita a collegamenti alla documentazione, che a volte non è così utile quando una persona sta cercando di vedere come una funzione può funzionare, dato un esempio. Altrimenti la maggior parte delle risposte SO sarebbero semplicemente link a php.net – kurdtpage

+0

@kurdtpage La documentazione php è una delle migliori documentazioni che conosca. Ci sono molti esempi molto buoni per ogni funzione e gli esempi per 'str_split' sono molto più dettagliati del suo esempio. –

6

Puoi anche accedere a $ s1 come un array, se hai solo bisogno di accedervi:

$s1 = "hello world"; 
echo $s1[0]; // -> h 
0
// 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; 
} 
2

Per coloro che cercano il modo più veloce per scorrere su stringhe in php, Ive ha preparato un test di riferimento.
Il primo metodo in cui si accede caratteri della stringa direttamente specificando la sua posizione tra parentesi e nel trattamento stringa come un array:

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

Io stesso pensato che il secondo è il metodo più veloce, ma mi sbagliavo.
Come con il secondo metodo (che viene utilizzato nella risposta accettata):

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

Questo metodo sta per essere più veloce perché stiamo usando una matrice vera e non assumendo uno per essere un array.

Chiamando l'ultima linea di ciascuno dei metodi di cui sopra per 1000000 volte portano a questi risultati di benchmarking:

Utilizzando string [i]
0.24960017204285 Seconds

Utilizzando str_split
0.18720006942749 Seconds

Ciò significa che il secondo metodo è molto più veloce.

25

stringa Iterate:

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

Questa sembra una risposta migliore perché risponde alla domanda - cioè come iterare su una stringa anziché "convertire in array". – Robin