Dividere le stringhe in Ruby usando il metodo String # split

A meno che l'input dell'utente non sia una singola parola o numero, tale input dovrà essere suddiviso o trasformato in un elenco di stringhe o numeri.

Ad esempio, se un programma richiede il tuo nome completo, incluso l'iniziale centrale, dovrà prima dividere quell'input in tre stringhe separate prima di poter lavorare con il tuo nome, secondo e cognome individuali. Questo si ottiene usando il String # spaccatura metodo.

Come funziona String # split

Nella sua forma più elementare, String # spaccatura accetta un singolo argomento: il delimitatore di campo come stringa. Questo delimitatore verrà rimosso dall'output e verrà restituita una matrice di stringhe divise sul delimitatore.

Quindi, nell'esempio seguente, supponendo che l'utente abbia inserito correttamente il proprio nome, dovresti ricevere un tre elementi Vettore dalla scissione.

#! / usr / bin / env ruby
stampa "Qual è il tuo nome completo?"
full_name = gets.chomp
name = full_name.split (")
mette "Il tuo nome è # name.first"
mette "Il tuo cognome è # name.last"

Se eseguiamo questo programma e inseriamo un nome, otterremo alcuni risultati previsti. Inoltre, si noti che prima il nome e name.last sono coincidenze. Il nome la variabile sarà un Vettore, e quelle due chiamate di metodo saranno equivalenti a nome [0] e name [-1] rispettivamente.

$ ruby ​​split.rb
Qual è il tuo nome completo? Michael C. Morin
Il tuo nome è Michael
Il tuo cognome è Morin

tuttavia, String # spaccatura è un po 'più intelligente di quanto pensi. Se l'argomento a String # spaccatura è una stringa, la usa davvero come delimitatore, ma se l'argomento è una stringa con un singolo spazio (come abbiamo usato), allora deduce che vuoi dividere su qualsiasi quantità di spazio bianco e che vuoi anche rimuovere qualsiasi spazio bianco principale.

Quindi, se dovessimo dargli un input leggermente malformato come

Michael C. Morin

(con spazi extra), quindi String # spaccatura farebbe comunque quello che ci si aspetta. Tuttavia, questo è l'unico caso speciale quando passi a Corda come primo argomento. Delimitatori di espressioni regolari

Puoi anche passare un'espressione regolare come primo argomento. Qui, String # spaccatura diventa un po 'più flessibile. Possiamo anche rendere il nostro piccolo nome che divide il codice un po 'più intelligente.

Non vogliamo il periodo alla fine dell'iniziale centrale. Sappiamo che è un'iniziale di mezzo e che il database non vorrà un periodo lì, quindi possiamo rimuoverlo mentre dividiamo. quando String # spaccatura corrisponde a un'espressione regolare, fa la stessa cosa esatta come se avesse appena abbinato un delimitatore di stringa: lo estrae dall'output e lo divide in quel punto.

Quindi, possiamo evolvere un po 'il nostro esempio:

$ cat split.rb
#! / usr / bin / env ruby
stampa "Qual è il tuo nome completo?"
full_name = gets.chomp
name = full_name.split (/ \.? \ s + /)
mette "Il tuo nome è # name.first"
mette "La tua seconda sigla è # name [1]"
mette "Il tuo cognome è # name.last"

Separatore record predefinito

Ruby non è molto grande nelle "variabili speciali" che potresti trovare in lingue come il Perl, ma String # spaccatura ne usa uno di cui devi essere consapevole. Questa è la variabile di separazione dei record predefinita, nota anche come $;.

È globale, qualcosa che non vedi spesso in Ruby, quindi se lo cambi, potrebbe influire su altre parti del codice: assicurati di cambiarlo al termine.

Tuttavia, tutto ciò che fa questa variabile è agire come valore predefinito per il primo argomento String # spaccatura. Per impostazione predefinita, questa variabile sembra essere impostata su zero. Tuttavia, se String # spaccaturaIl primo argomento è zero, lo sostituirà con una singola stringa di spazio.

Delimitatori a lunghezza zero

Se il delimitatore è passato a String # spaccatura è una stringa di lunghezza zero o un'espressione regolare, quindi String # spaccatura agirà in modo leggermente diverso. Non rimuoverà nulla dalla stringa originale e si dividerà su ogni carattere. Questo essenzialmente trasforma la stringa in una matrice di uguale lunghezza contenente solo stringhe di un carattere, una per ogni carattere della stringa.

Questo può essere utile per iterare sulla stringa ed è stato usato in pre-1.9.xe pre-1.8.7 (che eseguiva il backport di una serie di funzioni da 1.9.x) per iterare i caratteri in una stringa senza preoccuparsi di rompere multi- byte caratteri Unicode. Tuttavia, se ciò che vuoi veramente fare è iterare su una stringa e stai usando 1.8.7 o 1.9.x, probabilmente dovresti usare String # each_char anziché.

#! / usr / bin / env ruby
str = "Mi ha trasformato in un tritone!"
str.split ("). ognuno fa | c |
mette c
fine

Limitazione della lunghezza della matrice restituita

Quindi, tornando al nostro esempio di analisi del nome, cosa succede se qualcuno ha uno spazio nel suo cognome? Ad esempio, i cognomi olandesi possono spesso iniziare con "van" (che significa "di" o "da").

Vogliamo davvero solo un array di 3 elementi, quindi possiamo usare il secondo argomento per String # spaccatura che finora abbiamo ignorato. Il secondo argomento dovrebbe essere a Fixnum. Se questo argomento è positivo, al massimo, molti elementi verranno riempiti nella matrice. Quindi, nel nostro caso, vorremmo passare 3 per questo argomento.

#! / usr / bin / env ruby
stampa "Qual è il tuo nome completo?"
full_name = gets.chomp
name = full_name.split (/ \.? \ s + /, 3)
mette "Il tuo nome è # name.first"
mette "La tua seconda sigla è # name [1]"
mette "Il tuo cognome è # name.last"

Se lo eseguiamo di nuovo e gli diamo un nome olandese, funzionerà come previsto.

$ ruby ​​split.rb
Qual è il tuo nome completo? Vincent Willem van Gogh
Il tuo nome è Vincent
La tua iniziale centrale è Willem
Il tuo cognome è van Gogh

Tuttavia, se questo argomento è negativo (qualsiasi numero negativo), allora non ci sarà limite al numero di elementi nell'array di output e tutti i delimitatori finali appariranno come stringhe di lunghezza zero alla fine dell'array.

Questo è dimostrato in questo frammento IRB:

: 001> "this, is, a, test ,,,,". Split (',', -1)
=> ["this", "is", "a", "test", "", "", "", ""]