Hur man delar strängar i Ruby

Om ingången inte är ett enda ord eller ett nummer, måste den ingå dela 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.

Hur String # split fungerar

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

instagram viewer
namn först och name.last är tillfällen. De namn variabel kommer att vara en Arrayoch 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 den som avgränsaren, men om argumentet är en sträng med ett enda utrymme (som vi använde), då anger det att du vill dela upp någon mängd blanksteg och att du också vill ta bort alla ledande blanksteg.

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}"

Standard Record Separator

Rubin är inte riktigt stort 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 - se till att byta tillbaka den 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, kommer den att ersätta den med en enda rymdsträng.

Nolllängdavgränsare

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 backported a 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 multi-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

Begränsa längden på den returnerade arrayen

Så tillbaka till exemplet på vårt namn, vad händer om någon har ett utrymme i efternamnet? Till exempel kan holländska efternamn ofta börja med "skåpbil" (som betyder "av" eller "från").

Vi vill bara 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 (något negativt antal), 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 array.

Detta visas i detta IRB-utdrag:

: 001> "detta, är, ett, test" .split (',', -1)
=> ["detta", "är", "ett", "test", "", "", "", ""]
instagram story viewer