Pokud není uživatelský vstup jediné slovo nebo číslo, musí být tento vstup rozdělit nebo se změnil na seznam řetězců nebo čísel.
Například, pokud program požádá o vaše celé jméno, včetně středního iniciálu, bude nejprve nutné rozdělit tento vstup do tří samostatných řetězce než bude moci pracovat s vaším osobním křestním jménem, prostředním a příjmením. Toho je dosaženo pomocí String # split metoda.
Jak funguje String # split
Ve své nejzákladnější podobě String # split vezme jediný argument: oddělovač pole jako řetězec. Tento oddělovač bude odstraněn z výstupu a bude vráceno pole řetězců rozdělených na oddělovači.
V následujícím příkladu tedy za předpokladu, že uživatel správně zadá své jméno, byste měli obdržet tříprvek Pole z rozdělení.
#! / usr / bin / env ruby
print "Jaké je vaše celé jméno? "
full_name = gets.chomp
name = full_name.split ('')
vloží „Vaše jméno je # {name.first}“
vloží „Vaše příjmení je # {name.last}“
Pokud spustíme tento program a zadáme jméno, dostaneme očekávané výsledky. Také si všimněte, že
jméno první a name.last jsou náhody. název proměnná bude Pole, a tato dvě volání metod budou ekvivalentní jméno [0] a jméno [-1] resp.$ ruby split.rb
Jaké je vaše jméno a příjmení? Michael C. Morine
Vaše jméno je Michael
Vaše příjmení je Morin
Nicméně, String # split je o něco chytřejší, než si myslíte. Pokud argument String # split je řetězec, který opravdu používá jako oddělovač, ale pokud je argument řetězec s jediným mezerou (jak jsme použili), z toho vyvozuje, že se chcete rozdělit na libovolné množství mezer a že také chcete odstranit všechny mezery.
Pokud bychom tedy měli dát nějaké mírně deformované vstupy, jako je
Michael C. Morine
(s mezerami navíc) String # split by stále dělal, co se očekává. To je však jediný zvláštní případ, když projdete Tětiva jako první argument. Pravidelné oddělovače výrazů
Jako první argument můžete také předat regulární výraz. Tady, String # split se stává o něco flexibilnějším. Můžeme také udělat trochu inteligentnější rozdělovací kód pro malé jméno.
Nechceme období na konci střední iniciály. Víme, že se jedná o střední iniciál a databáze tam nebude chtít období, takže ji můžeme při rozdělení rozdělit. Když String # split odpovídá regulárnímu výrazu, dělá to samé přesně, jako kdyby právě souhlasilo s oddělovačem řetězců: vyjme jej z výstupu a v tom okamžiku jej rozdělí.
Můžeme tedy trochu vylepšit náš příklad:
$ cat split.rb
#! / usr / bin / env ruby
print "Jaké je vaše celé jméno? "
full_name = gets.chomp
name = full_name.split (/ \.? \ s + /)
vloží „Vaše jméno je # {name.first}“
vloží „Váš střední iniciál je # {name [1]}“
vloží „Vaše příjmení je # {name.last}“
Výchozí oddělovač záznamů
Rubín není opravdu velký na "speciální proměnné", které byste mohli najít v jazycích, jako je Perl, ale String # split používá jeden, musíte být vědomi. Toto je výchozí proměnná oddělovače záznamů, známá také jako $;.
Je to globální, něco, co v Ruby často nevidíte, takže pokud jej změníte, může to ovlivnit další části kódu - po dokončení jej nezapomeňte změnit zpět.
Všechny tyto proměnné však slouží jako výchozí hodnota pro první argument String # split. Ve výchozím nastavení je tato proměnná nastavena na nula. Nicméně, pokud String # splitPrvní argument je nula, nahradí jej jediným řetězcem mezer.
Oddělovače s nulovou délkou
Pokud oddělovač přešel na String # split je řetězec nulové délky nebo regulární výraz String # split bude se chovat trochu jinak. Z původního řetězce nic neodstraní a na každé postavě se rozdělí. Toto v podstatě změní řetězec na pole stejné délky obsahující pouze jednořetězcové řetězce, jeden pro každý znak v řetězci.
To může být užitečné pro iteraci řetězce a bylo použito v pre-1.9.xa pre-1.8.7 (což backportovalo počet funkcí od 1.9.x) iterovat přes znaky v řetězci bez obav o rozpad multi-byte Znaky Unicode. Pokud však opravdu chcete iterovat přes řetězec a používáte 1.8.7 nebo 1.9.x, měli byste pravděpodobně použít String # every_char namísto.
#! / usr / bin / env ruby
str = "Otočila mě v mloka!"
str.split (''). Každý do | c |
staví c
konec
Omezení délky vráceného pole
Takže zpět na příklad analýzy jména, co když má někdo ve svém příjmení mezeru? Například nizozemská příjmení mohou často začínat „van“ (což znamená „z“ nebo „od“).
Opravdu chceme pouze 3-element pole, takže můžeme použít druhý argument String # split které jsme dosud ignorovali. Očekává se, že druhým argumentem bude a Fixnum. Pokud je tento argument pozitivní, nanajvýš bude vyplněno mnoho prvků v poli. Takže v našem případě bychom za tento argument chtěli projít 3.
#! / usr / bin / env ruby
print "Jaké je vaše celé jméno? "
full_name = gets.chomp
name = full_name.split (/ \.? \ s + /, 3)
vloží „Vaše jméno je # {name.first}“
vloží „Váš střední iniciál je # {name [1]}“
vloží „Vaše příjmení je # {name.last}“
Pokud to znovu spustíme a dáme mu nizozemské jméno, bude to fungovat podle očekávání.
$ ruby split.rb
Jaké je vaše jméno a příjmení? Vincent Willem van Gogh
Vaše jméno je Vincent
Váš prostřední iniciál je Willem
Vaše příjmení je van Gogh
Pokud je však tento argument záporný (jakékoli záporné číslo), nebude počet žádných limitů omezen prvky ve výstupním poli a všechny koncové oddělovače se zobrazí jako řetězce nulové délky na konci pole.
Toto je demonstrováno v tomto fragmentu IRB:
: 001> "toto je, a, test" .split (',', -1)
=> ["toto", "je", "a", "test", "", "", "", ""]