Tenzij gebruikersinvoer een enkel woord of nummer is, moet die invoer worden gesplitst of omgezet in een lijst met tekenreeksen of getallen.
Als een programma bijvoorbeeld om uw volledige naam vraagt, inclusief middelste initiaal, moet het die invoer eerst in drie afzonderlijke tekenreeksen splitsen voordat het kan werken met uw individuele voornaam, middelste en achternaam. Dit wordt bereikt met behulp van de String # split methode.
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 tekenreeksen opgesplitst in het scheidingsteken wordt geretourneerd.
Dus in het volgende voorbeeld, ervan uitgaande dat de gebruiker zijn naam correct invoert, zou u een drie-elementen moeten ontvangen reeks van de splitsing.
#! / usr / bin / env ruby
print "Wat is uw volledige naam?"
full_name = gets.chomp
name = volledige_naam.split (")
zet "Uw voornaam is # name.first"
zet "Uw achternaam is # name.last"
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 reeks, en die twee methodeaanroepen zullen equivalent zijn 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 om String # split is een tekenreeks, het gebruikt dat inderdaad als het scheidingsteken, maar als het argument een tekenreeks is met een enkele spatie (zoals we gebruikten), komt het erop neer dat u wilt splitsen op een willekeurige hoeveelheid witruimte en dat u ook wilt verwijderen leidende witruimte.
Dus als we het een beetje misvormde invoer zouden geven, zoals
Michael C. Morin
(met extra spaties), dan String # split zou nog steeds doen wat verwacht wordt. Dat is echter het enige speciale geval wanneer u een Draad als het eerste argument. Reguliere expressie scheidingstekens
U kunt ook een reguliere uitdrukking doorgeven als het eerste argument. Hier, String # split wordt een beetje flexibeler. We kunnen onze kleine naamsplitsingscode ook een beetje slimmer maken.
We willen de punt niet aan het einde van de middelste initiaal. We weten dat het een middelste initiaal is en dat de database daar geen punt wil hebben, dus we kunnen het verwijderen terwijl we splitsen. Wanneer String # split komt overeen met een reguliere expressie, het doet precies hetzelfde alsof het net een stringscheidingsteken had gevonden: het haalt het uit de uitvoer en splitst het op dat punt.
Dus we kunnen ons voorbeeld een beetje evolueren:
$ cat split.rb
#! / usr / bin / env ruby
print "Wat is uw volledige naam?"
full_name = gets.chomp
name = volledige_naam.split (/ \.? \ s + /)
zet "Uw voornaam is # name.first"
zet "Uw middelste initiaal is # name [1]"
zet "Uw achternaam is # name.last"
Ruby is niet echt groot in "speciale variabelen" die je misschien in talen zoals Perl tegenkomt, maar String # split gebruikt er een waar je op moet letten. Dit is de standaard recordscheidingsvariabele, ook bekend als $;.
Het is een globaal, iets dat je niet vaak ziet in Ruby, dus als je het verandert, kan dit andere delen van de code beïnvloeden - zorg er gewoon voor dat je het terugzet wanneer je klaar bent.
Het enige dat deze variabele doet, is echter de standaardwaarde voor het eerste argument String # split. Standaard lijkt deze variabele te zijn ingesteld nul. Echter, als String # splitHet eerste argument is nul, het zal het vervangen door een enkele spatie string.
Als het scheidingsteken is doorgegeven aan String # split is een tekenreeks van nul lengte of reguliere expressie String # split zal een beetje anders handelen. Het verwijdert helemaal niets uit de originele string en splitst op elk karakter. Dit verandert de reeks in wezen in een reeks van gelijke lengte die alleen reeksen van één karakter bevat, één voor elk karakter in de reeks.
Dit kan handig zijn voor het herhalen van de string en werd gebruikt in pre-1.9.x en pre-1.8.7 (waarbij een aantal functies van 1.9.x werd teruggezet) om tekens in een string te herhalen zonder zorgen te maken over het verbreken van 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 String # each_char in plaats daarvan.
#! / usr / bin / env ruby
str = "Ze heeft me in een newt veranderd!"
str.split ("). elk doen | c |
zet c
einde
Dus terug naar ons voorbeeld van het ontleden van namen, wat als iemand een spatie in zijn achternaam heeft? Nederlandse achternamen kunnen bijvoorbeeld vaak beginnen met "van" (wat betekent "van" of "van").
We willen alleen echt een array met 3 elementen, dus we kunnen het tweede argument gebruiken om String # split die we tot nu toe hebben genegeerd. Het tweede argument is naar verwachting een Fixnum. Als dit argument hooguit positief is, worden er veel elementen in de array ingevuld. Dus in ons geval zouden we 3 voor dit argument willen passeren.
#! / usr / bin / env ruby
print "Wat is uw volledige naam?"
full_name = gets.chomp
name = volledige_naam.split (/ \.? \ s + /, 3)
zet "Uw voornaam is # name.first"
zet "Uw middelste initiaal is # name [1]"
zet "Uw 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 op het aantal elementen in de uitvoerarray en worden eventuele scheidingstekens weergegeven als tekenreeksen met lengte nul aan het einde van de array.
Dit wordt aangetoond in dit IRB-fragment:
: 001> "this, is, a, test ,,,,". Split (',', -1)
=> ["this", "is", "a", "test", "", "", "", ""]