Om ingången inte är ett enda ord eller ett nummer, måste den ingå delas eller förvandlas till en lista med strängar eller siffror.
Om ett program till exempel ber om ditt fulla namn, inklusive mellansinitial, måste det först dela in ingången i tre separata strängar innan det kan fungera med ditt individuella för-, mellan- och efternamn. Detta uppnås med hjälp av String # split metod.
I sin mest grundläggande form, String # split tar ett enda argument: fältavgränsaren som en sträng. Denna avgränsare kommer att tas bort från utgången och en rad strängar som delas på avgränsaren kommer att returneras.
Så i följande exempel, om du antar att användaren matar in sitt namn korrekt, bör du få ett treelement Array från splittringen.
#! / usr / bin / env ruby
tryck "Vad är ditt fulla namn?"
full_name = gets.chomp
name = full_name.split (")
sätter "Ditt förnamn är # name.first"
sätter "Ditt efternamn är # name.last"
Om vi kör detta program och anger ett namn får vi förväntade resultat. Observera också det namn först och name.last är tillfällen. De namn variabel kommer att vara en Array, och dessa två metodsamtal motsvarar namn [0] och name [-1] respektive.
$ ruby split.rb
Vad är ditt fullständiga namn? Michael C. Morin
Ditt förnamn är Michael
Ditt efternamn är Morin
dock, String # split är lite smartare än du skulle tro. Om argumentet till String # split är en sträng, den använder verkligen det som avgränsare, men om argumentet är en sträng med ett enda utrymme (som vi använde), så anger det att du vill dela upp någon mängd blanksteg och att du också vill ta bort alla ledande whitespace.
Så om vi skulle ge det lite missbildade input som
Michael C. Morin
(med extra utrymmen), då String # split skulle fortfarande göra vad som förväntas. Men det är det enda speciella fallet när du passerar en Sträng som det första argumentet. Regelbundna uttrycksavgränsare
Du kan också skicka ett regelbundet uttryck som det första argumentet. Här, String # split blir lite mer flexibel. Vi kan också göra vår lilla namndelningskod lite smartare.
Vi vill inte att perioden ska vara i slutet av den mellersta initialen. Vi vet att det är en mellaninitial och databasen vill inte ha en period där, så vi kan ta bort den medan vi delar upp. När String # split matchar ett regelbundet uttryck, det gör samma exakta som om det just hade matchat en strängavgränsare: det tar ut det från utgången och delar upp det vid den punkten.
Så vi kan utveckla vårt exempel lite:
$ katt split.rb
#! / usr / bin / env ruby
tryck "Vad är ditt fulla namn?"
full_name = gets.chomp
name = full_name.split (/ \.? \ s + /)
sätter "Ditt förnamn är # name.first"
sätter "Din mellaninitial är # name [1]"
sätter "Ditt efternamn är # name.last"
Ruby är inte riktigt stor på "specialvariabler" som du kan hitta på språk som Perl, men String # split använder en du måste vara medveten om. Det här är en standardvariabel för skivseparator, även känd som $;.
Det är ett globalt, något du inte ofta ser i Ruby, så om du ändrar det kan det påverka andra delar av koden - bara se till att ändra den tillbaka när du är klar.
Men all denna variabel är att fungera som standardvärdet för det första argumentet till String # split. Som standard verkar denna variabel vara inställd på noll. Men om String # splitDet första argumentet är noll, den kommer att ersätta den med en enda rymdsträng.
Om avgränsaren gick till String # split är en sträng med noll längd eller ett reguljärt uttryck String # split kommer att agera lite annorlunda. Det tar ingenting bort från originalsträngen och delas på varje tecken. Detta förvandlar i huvudsak strängen till en matris med samma längd som endast innehåller strängar med en karaktär, en för varje tecken i strängen.
Detta kan vara användbart för att iterera över strängen och användes i pre-1.9.x och pre-1.8.7 (som backporterade ett antal funktioner från 1.9.x) för att iterera över tecken i en sträng utan att oroa dig för att bryta upp flera byte Unicode-tecken. Om det du verkligen vill göra är att iterera över en sträng, och du använder 1.8.7 eller 1.9.x, bör du antagligen använda String # each_char istället.
#! / usr / bin / env ruby
str = "Hon förvandlade mig till en ny!"
str.split ("). varje do | c |
sätter c
slutet
Så tillbaka till exemplet på vårt namn, vad händer om någon har ett mellanrum i efternamnet? Till exempel kan holländska efternamn ofta börja med "van" (vilket betyder "av" eller "från").
Vi vill bara verkligen ha ett 3-element array, så vi kan använda det andra argumentet till String # split som vi hittills har ignorerat. Det andra argumentet förväntas vara ett Fixnum. Om detta argument är positivt, som mest, att många element kommer att fyllas i matrisen. Så i vårt fall skulle vi vilja bestämma 3 för detta argument.
#! / usr / bin / env ruby
tryck "Vad är ditt fulla namn?"
full_name = gets.chomp
name = full_name.split (/ \.? \ s + /, 3)
sätter "Ditt förnamn är # name.first"
sätter "Din mellaninitial är # name [1]"
sätter "Ditt efternamn är # name.last"
Om vi kör detta igen och ger det ett holländskt namn, kommer det att fungera som förväntat.
$ ruby split.rb
Vad är ditt fullständiga namn? Vincent Willem van Gogh
Ditt förnamn är Vincent
Din mellaninitial är Willem
Ditt efternamn är van Gogh
Men om detta argument är negativt (vilket negativt antal som helst) kommer det inte att finnas någon gräns för antalet element i utmatningsfältet och eventuella efterföljande avgränsare kommer att visas som strängar med noll längd i slutet av matrisen.
Detta visas i detta IRB-utdrag:
: 001> "detta, är, ett, test ,,,,". Split (',', -1)
=> ["detta", "är", "ett", "test", "", "", "", ""]