Hoe snaren te splitsen in Ruby

Tenzij gebruikersinvoer een enkel woord of getal is, moet die invoer zijn splitsen of veranderd in een lijst met strings of getallen.

Als een programma bijvoorbeeld om uw volledige naam vraagt, inclusief de middelste initiaal, moet het die invoer eerst in drie afzonderlijke delen splitsen snaren voordat het kan werken met uw individuele voor-, middel- en achternaam. Dit wordt bereikt met de String # split methode.

Hoe String # split werkt

In zijn meest basale vorm, String # split neemt een enkel argument: het veldscheidingsteken als een string. Dit scheidingsteken wordt uit de uitvoer verwijderd en een reeks strings die op het scheidingsteken zijn gesplitst, wordt geretourneerd.

Dus in het volgende voorbeeld, ervan uitgaande dat de gebruiker zijn naam correct heeft ingevoerd, zou u een drie-element moeten ontvangen Array uit de splitsing.

#! / usr / bin / env robijn
print "Wat is je volledige naam? "
volledige_naam = krijgt.chomp
name = volledige_naam.split ('')
zet "Uw voornaam is # {name.first}"
zet "Je achternaam is # {name.last}"
instagram viewer

Als we dit programma uitvoeren en een naam invoeren, krijgen we enkele verwachte resultaten. Merk ook op dat naam eerst en achternaam zijn toevalligheden. De naam variabele zal een zijn Array, en die twee methodeaanroepen zijn gelijk aan naam [0] en naam [-1] respectievelijk.

$ ruby ​​split.rb
Wat is je volledige naam? Michael C. Morin
Je voornaam is Michael
Je achternaam is Morin

Echter, String # split is een beetje slimmer dan je zou denken. Als het argument String # split is een string, het gebruikt dat inderdaad als scheidingsteken, maar als het argument een string is met een enkele spatie (zoals we gebruikten), dan leidt het af dat u wilt splitsen op een willekeurige hoeveelheid witruimte en dat u ook alle leidende witruimte wilt verwijderen.

Dus, als we het wat licht misvormde input zouden geven, zoals

Michael C. Morin

(met extra spaties) dan String # split zou nog steeds doen wat er verwacht wordt. Dat is echter het enige speciale geval wanneer u een Draad als eerste argument. Scheidingstekens voor reguliere expressies

U kunt ook een reguliere expressie doorgeven als eerste argument. Hier, String # split wordt een beetje flexibeler. We kunnen onze code voor het splitsen van kleine namen ook een beetje slimmer maken.

We willen de punt aan het einde van de middelste initiaal niet. We weten dat het een middelste initiaal is en dat de database daar geen periode wil, dus we kunnen deze verwijderen terwijl we splitsen. Wanneer String # split komt overeen met een reguliere expressie, het doet precies hetzelfde alsof het net een tekenreeksscheidingsteken had: het haalt het uit de uitvoer en splitst het op dat punt.

We kunnen ons voorbeeld dus een beetje ontwikkelen:

$ cat split.rb
#! / usr / bin / env robijn
print "Wat is je volledige naam? "
volledige_naam = krijgt.chomp
name = volledige_naam.split (/ \.? \ s + /)
zet "Uw voornaam is # {name.first}"
zet "Uw middelste initiaal is # {naam [1]}"
zet "Je achternaam is # {name.last}"

Standaard Record Separator

Robijn is niet echt groot op "speciale variabelen" die je zou kunnen vinden in talen zoals Perl, maar String # split gebruikt er een waar u op moet letten. Dit is de standaard variabele voor het scheiden van records, ook wel bekend als $;.

Het is een globaal iets dat je niet vaak ziet in Ruby, dus als je het verandert, kan het andere delen van de code beïnvloeden - zorg er wel voor dat je het terugzet als je klaar bent.

Alles wat deze variabele doet, is echter de standaardwaarde voor het eerste argument String # split. Standaard lijkt deze variabele te zijn ingesteld op nihil. Echter, als String # split's eerste argument is nihil, het zal het vervangen door een enkele spatie string.

Scheidingstekens zonder lengte

Als het scheidingsteken is doorgegeven aan String # split is dan een tekenreeks van nul lengte of reguliere expressie String # split zal een beetje anders werken. Het verwijdert helemaal niets uit de originele string en splitst op elk personage. Dit verandert de string in wezen in een array van gelijke lengte met alleen strings van één karakter, één voor elk karakter in de string.

Dit kan handig zijn voor iteratie over de string en werd gebruikt in pre-1.9.x en pre-1.8.7 (die een aantal functies van 1.9.x) om karakters in een string te herhalen zonder je zorgen te hoeven maken over het uiteenvallen multi-byte Unicode-tekens. Als u echter echt een string wilt herhalen en u gebruikt 1.8.7 of 1.9.x, moet u waarschijnlijk Tekenreeks # each_char in plaats daarvan.

#! / usr / bin / env robijn
str = "Ze veranderde me in een salamander!"
str.split (''). elk doen | c |
zet c
einde

De lengte van de geretourneerde array beperken

Dus terug naar ons voorbeeld van het ontleden van de naam, wat als iemand een spatie in zijn achternaam heeft? Zo kunnen Nederlandse achternamen vaak beginnen met "van" (betekenis "van" of "van").

We willen alleen echt een 3-element matrix, dus we kunnen het tweede argument gebruiken String # split die we tot nu toe hebben genegeerd. Het tweede argument is naar verwachting a Fixnum. Als dit argument hooguit positief is, zullen veel elementen in de array worden ingevuld. Dus in ons geval zouden we 3 willen doorgeven voor dit argument.

#! / usr / bin / env robijn
print "Wat is je volledige naam? "
volledige_naam = krijgt.chomp
name = volledige_naam.split (/ \.? \ s + /, 3)
zet "Uw voornaam is # {name.first}"
zet "Uw middelste initiaal is # {naam [1]}"
zet "Je achternaam is # {name.last}"

Als we dit opnieuw uitvoeren en het een Nederlandse naam geven, werkt het zoals verwacht.

$ ruby ​​split.rb
Wat is je volledige naam? Vincent Willem van Gogh
Je voornaam is Vincent
Je middelste initiaal is Willem
Je achternaam is van Gogh

Als dit argument echter negatief is (elk negatief getal), is er geen limiet aan het aantal elementen in de uitvoerarray en eventuele scheidingstekens achteraan verschijnen aan het einde van de matrix.

Dit wordt gedemonstreerd in dit IRB-fragment:

: 001> "dit is een test" .split (',', -1)
=> ["this", "is", "a", "test", "", "", "", ""]
instagram story viewer