Как да разделите струните в Руби

click fraud protection

Освен ако потребителят не е една дума или число, това въвеждане ще трябва да бъде разцепване или се превърна в списък на низове или числа.

Например, ако програма поиска вашето пълно име, включително средното начално, първо ще трябва да раздели този вход на три отделни струни преди да може да работи с вашето лично име, средно и фамилно име. Това се постига с помощта на String # сплит метод.

Как работи String # split

В най-основната си форма, String # сплит взема един аргумент: разделителят на полето като низ. Този разделител ще бъде премахнат от изхода и масив от низове, разделени на разделителя, ще бъде върнат.

Така че в следващия пример, ако приемем, че потребителят въведе правилно името си, трябва да получите триелемент Array от разцеплението.

#! / usr / bin / env рубин
print "Какво е твоето пълно име? "
full_name = get.chomp
name = full_name.split ('')
поставя "Вашето име е # {name.first}"
поставя "Вашето фамилно име е # {name.last}"

Ако стартираме тази програма и въведем име, ще получим някои очаквани резултати. Също така имайте предвид това

instagram viewer
name.first и фамилия са съвпадения. Най- име променлива ще бъде Arrayи тези два метода ще бъдат еквивалентни на име [0] и Име [-1] съответно.

$ ruby ​​split.rb
Какво е цялото ти име? Майкъл С. Морен
Вашето първо име е Майкъл
Вашето фамилно име е Морин

Въпреки това, String # сплит е малко по-умна, отколкото бихте си мислили. Ако аргументът до String # сплит е низ, той наистина го използва като разделител, но ако аргументът е низ с едно интервал (както използвахме), след това се стига до заключението, че искате да разделите на произволно количество бяло пространство и че също така искате да премахнете всяко водещо бяло пространство.

Така че, ако искаме да му дадем някакво леко деформирано въвеждане като

Майкъл С. Морен

(с допълнителни интервали), след това String # сплит все още би направил това, което се очаква. Това обаче е единственият специален случай, когато преминете а низ като първи аргумент. Разделители за регулярна експресия

Можете също така да предавате редовен израз като първи аргумент. Тук, String # сплит става малко по-гъвкав. Можем също така да направим нашия код за разделяне на малко име малко по-интелигентен.

Не искаме периода в края на средната начална. Знаем, че това е средно начално и базата данни няма да иска период там, така че можем да го премахнем, докато се разделим. Кога String # сплит съвпада с обикновен израз, той прави същото точно нещо, както ако току-що е съвпадал с разделител на низове: изважда го от изхода и го разделя в този момент.

Така че, можем да развием нашия пример малко:

$ cat split.rb
#! / usr / bin / env рубин
print "Какво е твоето пълно име? "
full_name = get.chomp
name = full_name.split (/ \.? \ s + /)
поставя "Вашето име е # {name.first}"
поставя "Вашият среден начален номер е # {name [1]}"
поставя "Вашето фамилно име е # {name.last}"

Разделител за запис по подразбиране

рубин всъщност не е голям за „специални променливи“, които може да намерите на езици като Perl, но String # сплит използва един, който трябва да сте наясно. Това е променлива разделител на записи по подразбиране, известна също като $;.

Това е глобално нещо, което не виждате често в Ruby, така че ако го промените, това може да повлияе на други части от кода - просто не забравяйте да го промените обратно, когато приключите.

Въпреки това, цялата тази променлива е да действа като стойност по подразбиране за първия аргумент на String # сплит. По подразбиране тази променлива изглежда е зададена нула. Ако обаче String # сплитПървият аргумент е нула, ще го замени с един интервал от интервал

Разделители с нулева дължина

Ако разделителят премина към String # сплит е низ с нулева дължина или редовен израз, тогава String # сплит ще действа малко по-различно. Тя няма да премахне нищо от оригиналния низ и ще се раздели на всеки знак. Това по същество превръща низ в масив с еднаква дължина, съдържащ само един символен низ, по един за всеки символ в низа.

Това може да бъде полезно за повторение на низа и се използва в pre-1.9.x и pre-1.8.7 (които поддържат a брой функции от 1.9.x) за повторение на символи в низ, без да се притеснявате дали ще се разделим мулти-байт Unicode символи. Ако обаче наистина искате да направите итерация над низ и използвате 1.8.7 или 1.9.x, вероятно трябва да използвате String # each_char вместо.

#! / usr / bin / env рубин
str = "Тя ме превърна в тритон!"
str.split (''). всеки do | c |
поставя в
край

Ограничаване на дължината на върнатия масив

Така че обратно към нашия пример за анализ на име, какво става, ако някой има интервал в фамилното си име? Например, холандските фамилни имена често могат да започват с „ван“ (което означава „на“ или „от“).

Ние наистина наистина искаме 3-елемент масив, за да можем да използваме втория аргумент за String # сплит които досега игнорирахме. Очаква се вторият аргумент да бъде a Fixnum. Ако този аргумент е положителен, най-много, че много елементи ще бъдат попълнени в масива. Така че в нашия случай бихме искали да преминем 3 за този аргумент.

#! / usr / bin / env рубин
print "Какво е твоето пълно име? "
full_name = get.chomp
name = full_name.split (/ \.? \ s + /, 3)
поставя "Вашето име е # {name.first}"
поставя "Вашият среден начален номер е # {name [1]}"
поставя "Вашето фамилно име е # {name.last}"

Ако отново стартираме това и му дадем холандско име, то ще действа както се очаква.

$ ruby ​​split.rb
Какво е цялото ти име? Винсент Вилем ван Гог
Вашето първо име е Винсент
Вашият среден начален е Вилем
Вашето фамилно име е Ван Гог

Ако обаче този аргумент е отрицателен (всяко отрицателно число), тогава няма да има ограничение за броя на елементите в изходния масив и всички последващи разделители ще се показват като низове с дължина в края на масив.

Това е демонстрирано в този фрагмент на IRB:

: 001> "това е, е, тест" .split (',', -1)
=> ["това", "е", "а", "тест", "", "", "", ""]
instagram story viewer