Sådan deler man strenge i Ruby

Medmindre brugerinput er et enkelt ord eller et nummer, skal denne input være dele eller forvandlet til en liste over strenge eller tal.

For eksempel, hvis et program beder om dit fulde navn, inklusive midt-initial, er det først nødvendigt at opdele dette input i tre separate strygere før det kan arbejde med dit individuelle for-, mellem- og efternavn. Dette opnås ved hjælp af Streng # split metode.

Hvordan String # split fungerer

I sin mest basale form, Streng # split tager et enkelt argument: feltafgrænseren som en streng. Denne afgrænser fjernes fra output, og en række strenge, der er delt på afgrænseren, returneres.

Så i det følgende eksempel, hvis brugeren indtaster deres navn korrekt, skal du modtage et treelement Array fra split.

#! / usr / bin / env ruby
print "Hvad er dit fulde navn? "
full_name = gets.chomp
name = full_name.split ('')
sætter "Dit fornavn er # {name.first}"
sætter "Dit efternavn er # {name.last}"

Hvis vi kører dette program og indtaster et navn, får vi nogle forventede resultater. Bemærk også at

instagram viewer
name.first og name.last er tilfældigheder. Det navn variabel vil være en Array, og disse to metodekald svarer til navn [0] og navn [-1] henholdsvis.

$ ruby ​​split.rb
Hvad er dit fulde navn? Michael C. Morin
Dit fornavn er Michael
Dit efternavn er Morin

Imidlertid, Streng # split er lidt smartere end du skulle tro. Hvis argumentet til Streng # split er en streng, bruger den den faktisk som afgrænser, men hvis argumentet er en streng med et enkelt mellemrum (som vi brugte), så giver det udtryk for, at du vil opdele en hvilken som helst mængde hvidafstand, og at du også ønsker at fjerne ethvert førende hvidrum.

Så hvis vi skulle give det nogle lidt misdannede input som f.eks

Michael C. Morin

(med ekstra mellemrum) Streng # split ville stadig gøre, hvad der forventes. Det er dog det eneste specielle tilfælde, når du passerer en Snor som det første argument. Regelmæssige ekspressionsafgrænsere

Du kan også videregive et regelmæssigt udtryk som det første argument. Her, Streng # split bliver lidt mere fleksibel. Vi kan også gøre vores lille navnopdelingskode lidt smartere.

Vi vil ikke have perioden i slutningen af ​​den midterste initial. Vi ved, at det er en melleminitial, og databasen vil ikke have en periode der, så vi kan fjerne den, mens vi deler. Hvornår Streng # split matcher et almindeligt udtryk, det gør samme nøjagtige ting, som om det netop havde matchet en strengafgrænser: det tager det ud af output og opdeler det på det tidspunkt.

Så vi kan udvikle vores eksempel lidt:

$ kat split.rb
#! / usr / bin / env ruby
print "Hvad er dit fulde navn? "
full_name = gets.chomp
name = full_name.split (/ \.? \ s + /)
sætter "Dit fornavn er # {name.first}"
sætter "Din midterste initial er # {navn [1]}"
sætter "Dit efternavn er # {name.last}"

Standard Record Separator

Rubin er ikke rigtig stor på "specielle variabler", som du måske finder på sprog som Perl, men Streng # split bruger en, du skal være opmærksom på. Dette er standardoptagelseparatorvariablen, også kendt som $;.

Det er et globalt, noget du ikke ofte ser i Ruby, så hvis du ændrer det, kan det påvirke andre dele af koden - bare sørg for at ændre den tilbage, når du er færdig.

Imidlertid fungerer al denne variabel som standardværdien for det første argument til Streng # split. Som standard ser denne variabel ud til at være indstillet til nul. Men hvis Streng # split's første argument er nul, erstatter den med en enkelt mellemrumstreng.

Nul-længde afgrænsere

Hvis afgrænser gik til Streng # split er en streng med nul længde eller et regulært udtryk Streng # split vil handle lidt anderledes. Det fjerner overhovedet intet fra den originale streng og opdeles på alle tegn. Dette vender i det væsentlige strengen til en matrix med samme længde, der kun indeholder strenge med én karakter, en for hvert tegn i strengen.

Dette kan være nyttigt til iterering over strengen og blev brugt i pre-1.9.x og pre-1.8.7 (som backported a antal funktioner fra 1.9.x) til at itereere over tegn i en streng uden at bekymre dig om at bryde sammen multi-byte Unicode-tegn. Men hvad du virkelig ønsker at gøre, er at iterere over en streng, og du bruger 1.8.7 eller 1.9.x, skal du sandsynligvis bruge Streng # each_char i stedet.

#! / usr / bin / env ruby
str = "Hun forvandlede mig til en newt!"
str.split (''). hver do | c |
sætter c
ende

Begrænsning af længden af ​​det returnerede array

Så tilbage til eksempeleksemplet på vores navn, hvad nu, hvis nogen har et mellemrum i efternavnet? For eksempel kan hollandske efternavne ofte begynde med "van" (betyder "af" eller "fra").

Vi ønsker kun virkelig et 3-element matrix, så vi kan bruge det andet argument til Streng # split som vi hidtil har ignoreret. Det andet argument forventes at være et Fixnum. Hvis dette argument højst er positivt, at mange elementer vil blive udfyldt i matrixen. Så i vores tilfælde ønsker vi at give 3 til dette argument.

#! / usr / bin / env ruby
print "Hvad er dit fulde navn? "
full_name = gets.chomp
name = full_name.split (/ \.? \ s + /, 3)
sætter "Dit fornavn er # {name.first}"
sætter "Din midterste initial er # {navn [1]}"
sætter "Dit efternavn er # {name.last}"

Hvis vi kører dette igen og giver det et hollandsk navn, fungerer det som forventet.

$ ruby ​​split.rb
Hvad er dit fulde navn? Vincent Willem van Gogh
Dit fornavn er Vincent
Din midterste initial er Willem
Dit efternavn er van Gogh

Men hvis dette argument er negativt (et hvilket som helst negativt tal), vil der ikke være nogen grænse for antallet af elementer i output-arrayet og eventuelle baggrundsafgrænsere vises som strenge med nul længde i slutningen af array.

Dette demonstreres i dette IRB-uddrag:

: 001> "dette, er, en, test" .split (',', -1)
=> ["dette", "er", "en", "test", "", "", "", ""]