Функція Ruby для видалення всіх пробілів?


573

Яка функція Ruby, щоб видалити всі пробіли? Я шукаю щось на зразок PHP trim()?


36
Ваше питання не зрозуміло: Ви хочете видалити всі пробіли чи хочете позбутися провідних та задніх пробілів?
Сінан Юнюр

25
Пробіли PHP trim()пробілів " від початку та до кінця рядка " (як зазначено в документації ), він не видаляє "всі пробіли".
Тадек

3
Коли ви сумніваєтесь, подивіться онлайн-документацію Ruby для класу String (див. Смужку нижче).
Merovex

2
Зауважте, що всі відповіді, які використовують String#stripабо співпадають /\s+/, видалять лише пробіли ASCII. Якщо ви хочете переконатись, що будь-яка пробільна область, що не належить до ASCII, також захоплюється (наприклад, HTML &nbsp), дивіться дивно непопулярний відповідь від @EBooker.
MatzFan

1
Шкода, що такі великі відповіді не можуть отримати остаточну гідність того, хто приймається
Нова Олександрія,

Відповіді:


846

Якщо ви хочете видалити лише провідні та кінцеві пробіли (наприклад, обробка PHP), ви можете використовувати .strip, але якщо ви хочете видалити всю пробіл, ви можете використовувати .gsub(/\s+/, "")замість цього.


5
Чи означає "/ \ s + /" простий пробіл?
Рейлик для початківців

54
\ s + означає 1 або більше символів пробілу (пробіл, новий рядок, вкладка). // оточуючі показують, що це регулярний вираз.
dylanfm

3
Це не еквівалентно обробці ()
Бретт Холт

6
смуга була саме те, що я шукав, дякую за гарне запитання та awnser!
Франсуа

15
@BrettHolt Вираз gsub не є тим самим, як обрізка, але запитувач включав фразу "весь пробіл", яка також не відрізняється від обрізки. Тому я дав альтернативи.
joel.neely

494
s = "I have white space".delete(' ')

І щоб наслідувати trim()функцію PHP :

s = "   I have leading and trailing white space   ".strip

12
це набагато читабельніше, ніж регулярний вираз, чому він не такий популярний?
ckarbass

89
@ckarbass: Тому що багато людей віддають перевагу надмірно складним рішенням простих проблем. Це відходить від досвіду.
Ред С.

97
@ckarbass @Ed S. Це не так популярно, оскільки воно не те саме. В оригінальному запитанні було використано словосполучення "весь пробіл", що включає вкладки, нові рядки тощо. Запропонована відповідь не видалить інших символів пробілу. Що стосується "надмірно складного", я пропоную порівнювати простий регулярний вираз із .delete(' ').delete('\t').delete('\n') ..., який є надмірно багатослівним і дає багато можливостей для помилок помилок та помилок.
joel.neely

13
@ joel.neely: Я давно відповів на це питання, але прочитав це питання ще раз, уважніше. ОП попросила "функцію для видалення всіх пробілів" , але потім попросила "щось на зразок обрізки PHP ()" . Отже, трохи важко точно знати, чого вони тут хочуть. trim()звичайно не видаляє нові рядки та інші символи пробілу. Ви обираєте одну інтерпретацію розпливчастого питання.
Ed S.

4
@ joel.neely: З цього приводу я погоджуюся, що рішення, яке виходить за межі буквальної інтерпретації питання, є кращим у цьому випадку (тобто, регулярний вираз, видаляючи всі символи, які становлять пробіл, а не рядок delete()викликів.)
Ed S.

163

Відповідна відповідь:

"   clean up my edges    ".strip

повертає

"clean up my edges"

Це я забув. Я знав, що існує метод видалення пробілів, який би робив це за замовчуванням, якщо не було передано жодних аргументів. +1
Ed S.

Це еквівалентно обробці. Будь ласка, зверніться до цитати з @Tadeck вище.
Бретт Холт

3
Якщо є можливість, що змінна є nil, не забудьте запустити .to_sметод перед запуском смужки, щоб стрип-метод не викликав помилку. Вих. str=nil; str.to_s.strip #=> ""
scarver2

Я віддаю перевагу some_data.strip! якщо some_data.is_a? Рядок
slindsey3000

156

String#strip - видаліть усе пробіли від початку та до кінця.

String#lstrip - тільки з самого початку.

String#rstrip - тільки з кінця.

String#chomp(без аргументів) - видаляє роздільники рядків ( \nабо \r\n) з кінця.

String#chop - видаляє останній символ.

String#delete- x.delete(" \t\r\n")- видаляє всі перелічені пробіли.

String#gsub- x.gsub(/[[:space:]]/, '')- видаляє всі пробіли, включаючи однокодові .


Примітка . Усі вищевказані методи повертають нову рядок замість мутації оригіналу. Якщо ви хочете змінити рядок на місці, зателефонуйте до відповідного методу !в кінці.


У прикладі String # delete, як видається, використовується регулярний вираз, але він \sзнаходиться в лапках замість косої частини. Крім того, я не зміг знайти жодної згадки в документації, що видалення може взяти регулярний вираз як аргумент.
lethbear

@slothbear, це не регулярний вираз, це невеликий набір шаблонів, що нагадують регулярні виразки. Щодо документації, #deleteяк кажуть, працює аналогічно #count. Ви можете спробувати і в консолі.
ndnenkov

Дякую, що ви навчили мене чогось нового. А також дякую за нагадування про те, що спробувати речі в найменшому можливому контексті (командний рядок).
lethbear

1
@SeinopSys Я хотів зберегти цю відповідь лише Рубі.
ndnenkov

2
Лише остаточний приклад у цій відповіді привертає жахливий ASCII 160 "нерозбиваючий простір", обрив веб-скребків. #stripне. Див stackoverflow.com/questions/4859438 / ...
MatzFan

95
"1232 23 2 23 232 232".delete(' ')
=> "123223223232232"

Видалення працює швидше =)

user         system     total      real
gsub, s      0.180000   0.010000   0.190000 (0.193014)
gsub, s+     0.200000   0.000000   0.200000 (0.196408)
gsub, space  0.220000   0.000000   0.220000 (0.222711)
gsub, join   0.200000   0.000000   0.200000 (0.193478)
delete       0.040000   0.000000   0.040000 (0.045157)

1
але це видаляє лише spacesне всіwhite spaces
Гавриїл

1
delete(" \t\r\n")подбає про типовий пробіл, і все ж швидше, ніж gsub.
Сет Джеффірі

94

Якщо ви використовуєте Rails / ActiveSupport , ви можете використовувати squishметод. Він видаляє пробіл на обох кінцях рядка і об'єднує кілька пробілів в один простір.

Наприклад, наприклад.

" a  b  c ".squish

призведе до:

"a b c"

Перевірте це посилання від api.rubyonrails.org .


4
Зауважте, що відповіді, що стосуються лише посилань, не відштовхують, відповіді SO повинні бути кінцевою точкою пошуку рішення (проти ще однієї зупинки посилань, яка, як правило, затягується з часом). Просимо додати тут окремий конспект, зберігаючи посилання як орієнтир.
Клеопатра

2
Я думаю, що ця відповідь була достатньо поясненою, і той факт, що посилання було посиланням, оскільки сама відповідь була зрозумілою. Ця функція була гарна, дякую
ksugiarto

4
Це від ActiveSupport. Для його використання вам не потрібні всі Rails, але вам знадобиться принаймні ActiveSupport іrequire 'active_support/core_ext/string/filters'
Justin Force

2
Щоб було зрозуміло, це будь-який пробіл. Напр."a \t \n \f \r \v b".squish == "a b"
Purplejacket

47

Це трохи пізно, але будь-хто інший на цій сторінці в Google може зацікавити цю версію -

Якщо ви хочете очистити шматок заздалегідь відформатованого тексту, який, можливо, користувач якось вирізав і вставив у вашу програму, але збережіть міжряддя, спробуйте:

content = "      a big nasty          chunk of     something

that's been pasted                        from a webpage       or something        and looks 

like      this

"

content.gsub(/\s+/, " ").strip

#=> "a big nasty chunk of something that's been pasted from a webpage or something and looks like this"

33
Можна також використати squishметод Rails : apidock.com/rails/String/squish
Phillip Koebbe

5
Або якщо у вас немає Rails і у вас немає нових рядків, це squeeze(" ")може спрацювати.
Ендрю Грімм

45

.stripМетод Рубі виконує PHP еквівалентно trim().

Щоб видалити всі пробіли:

"  leading    trailing   ".squeeze(' ').strip
=> "leading trailing"

@Tass дав мені зрозуміти, що моя оригінальна відповідь видаляє подвійні літери підряд - YUCK! З тих пір я перейшов на метод сквош, який розумніший щодо таких випадків, якщо використовувати рамки Rails.

require 'active_support/all'
"  leading    trailing   ".squish
=> "leading trailing"

"  good    men   ".squish
=> "good men"

Цитуйте: http://apidock.com/rails/String/squish


1
Це видалить "приєднані" дублікати символів. "good men".squeeze.stripповернеться"god men"
Тасс

1
Дякуємо, що вказали на це @Tass. Я відредагував свою відповідь на користь методу сквіш.
scarver2

1
+1 для "копій літер поспіль". Я не міг придумати спосіб описати сценарій. Молодці! :-)
Tass

26
" Raheem Shaik ".strip

Це видалить ліві та праві бічні пробіли. Цей код дасть нам:"Raheem Shaik"


20

Також не забувайте:

$ s = "   I have white space   ".split
=> ["I", "have", "white", "space"]

6
Так s.split.join зробить роботу.
Пьотр Брудні

1
Це добре, коли повторюється:[" Hello World", "Big Giraffe "].map(&:split).map(&:join) #=> ["HelloWorld", "BigGiraffe"]
tbloncar

20

split.join вибухне всі пробіли в будь-якій точці рядка.

"  a b  c    d     ".split.join
> "abcd"

Набирати та запам’ятовувати його легко, тому це приємно на консолі та для швидкого злому. Напевно, не вітається в серйозному коді, хоча це маскує наміри.

(Виходячи з коментаря Піотра у відповіді Джастікуля вище.)


1
Багато, велике спасибі за цей коментар :-) Це єдиний метод, який працює, якщо у вас довга струна, яка схожа на абзац.
Бумеранж

12

Ви можете спробувати це

"Some Special Text Values".gsub(/[[:space:]]+/, "")

Використання : space: видаляє нерозривний простір разом із звичайним простором.


1
Це насправді найкраща відповідь IMHO, так як у дикому вигляді HTML &nbspта будь-які інші пробіли, що не належать до ASCII, не будуть видалені String#stripабо узгоджені користувачем /\s/. Дивіться розділ "POSIX
дужкові

8

Використовуйте gsub або видаліть. Різниця полягає в тому, що gsub може видалити вкладки, а видалити не вдається. Іноді у вас є вкладки у файлах, які додаються редакторами.

a = "\tI have some whitespaces.\t"
a.gsub!(/\s/, '')  #=>  "Ihavesomewhitespaces."
a.gsub!(/ /, '')   #=>  "\tIhavesomewhitespaces.\t"
a.delete!(" ")     #=>  "\tIhavesomewhitespaces.\t"
a.delete!("/\s/")  #=>  "\tIhavesomewhitespaces.\t"
a.delete!('/\s/')  #=>  using single quote is unexpected, and you'll get "\tI have ome whitepace.\t"

8

Існує багато способів:
видалити пробіл з обох сторін:

Начебто як обробка php ()

Foo_bar.strip

Щоб видалити всі пробіли:

Foo_bar.gsub(/ /, "")

Щоб видалити всі пробіли:

Foo_bar.gsub(/\s/, "")


6

Метод gsub буде чудово.
Метод gsub може викликати рядок і каже:

a = "this is a string"
a = a.gsub(" ","")
puts a
#Output: thisisastring

Метод gsub шукає кожне виникнення першого аргументу та замінює його другим аргументом. У цьому випадку він замінить кожен пробіл у рядку та видалить його.

Ще один приклад:

b = "the white fox has a torn tail"

Давайте замінимо кожне виникнення літери "t" на велику "T"

b = b.gsub("t","T")
puts b 
#Output: The whiTe fox has a Torn Tail

5

Для поведінки, що відповідає PHP trim, найпростішим методом є використання String#stripметоду, наприклад:

string = "  Many have tried; many have failed!    "
puts "Original [#{string}]:#{string.length}"
new_string = string.strip
puts "Updated  [#{new_string}]:#{new_string.length}"

У Ruby також є редакція на місці, яка також називається String.strip!(зверніть увагу на "!"). Для цього не потрібно створити копію рядка, а для деяких застосувань це може бути значно швидше:

string = "  Many have tried; many have failed!    "
puts "Original [#{string}]:#{string.length}"
string.strip!
puts "Updated  [#{string}]:#{string.length}"

Обидві версії дають такий вихід:

Original [  Many have tried; many have failed!    ]:40
Updated  [Many have tried; many have failed!]:34

Я створив орієнтир, щоб перевірити ефективність деяких основних застосувань stripта strip!, а також деяких альтернатив. Тест такий:

require 'benchmark'

string = 'asdfghjkl'
Times = 25_000

a = Times.times.map {|n| spaces = ' ' * (1+n/4); "#{spaces}#{spaces}#{string}#{spaces}" }
b = Times.times.map {|n| spaces = ' ' * (1+n/4); "#{spaces}#{spaces}#{string}#{spaces}" }
c = Times.times.map {|n| spaces = ' ' * (1+n/4); "#{spaces}#{spaces}#{string}#{spaces}" }
d = Times.times.map {|n| spaces = ' ' * (1+n/4); "#{spaces}#{spaces}#{string}#{spaces}" }

puts RUBY_DESCRIPTION
puts "============================================================"
puts "Running tests for trimming strings"

Benchmark.bm(20) do |x|
  x.report("s.strip:")                 { a.each {|s| s = s.strip } }
  x.report("s.rstrip.lstrip:")         { a.each {|s| s = s.rstrip.lstrip } }
  x.report("s.gsub:")                  { a.each {|s| s = s.gsub(/^\s+|\s+$/, "") } }
  x.report("s.sub.sub:")               { a.each {|s| s = s.sub(/^\s+/, "").sub(/\s+$/, "") } }

  x.report("s.strip!")                 { a.each {|s| s.strip! } }
  x.report("s.rstrip!.lstrip!:")       { b.each {|s| s.rstrip! ; s.lstrip! } }
  x.report("s.gsub!:")                 { c.each {|s| s.gsub!(/^\s+|\s+$/, "") } }
  x.report("s.sub!.sub!:")             { d.each {|s| s.sub!(/^\s+/, "") ; s.sub!(/\s+$/, "") } }
end

Ось такі результати:

ruby 2.2.5p319 (2016-04-26 revision 54774) [x86_64-darwin14]
============================================================
Running tests for trimming strings
                           user     system      total        real
s.strip:               2.690000   0.320000   3.010000 (  4.048079)
s.rstrip.lstrip:       2.790000   0.060000   2.850000 (  3.110281)
s.gsub:               13.060000   5.800000  18.860000 ( 19.264533)
s.sub.sub:             9.880000   4.910000  14.790000 ( 14.945006)
s.strip!               2.750000   0.080000   2.830000 (  2.960402)
s.rstrip!.lstrip!:     2.670000   0.320000   2.990000 (  3.221094)
s.gsub!:              13.410000   6.490000  19.900000 ( 20.392547)
s.sub!.sub!:          10.260000   5.680000  15.940000 ( 16.411131)

3

Мої особисті переваги - це використання методу .tr

як і в:

string = "this is a string to smash together"

string.tr(' ', '') # => "thisisastringtosmashtogether"

Дякуючи @FrankScmitt за те, що він вказав, що для цього видалити весь пробіл (а не лише пробіли), вам потрібно буде записати його як таке:

string = "this is a string with tabs\t and a \nnewline"

string.tr(" \n\t", '') # => "thisisastringwithtabsandanewline"

але це видаляє лише spaces, а неall white spaces
Гавриїл

Щоб видалити всі пробіли (пробіл, вкладка, новий рядок), спробуйте скористатися s.tr(" \t\n", '')натомість.
Френк Шмітт

@Gavriel - я неправильно прочитав / неправильно зрозумів питання, дякую, що вказав на це.
Джеремі Гюнтер

@FrankSchmitt Я додав ваше виправлення у свою відповідь, щоб більш правильно відповісти на питання ОП. Дякую, що виправили мене.
Джеремі Гюнтер

3

Я намагався це зробити, оскільки хотів використовувати "заголовок" записів як ідентифікатор у представленні, але в заголовках було пробіли.

рішення:

record.value.delete(' ') # Foo Bar -> FooBar

1

Рубі .scan()та .join()методи String також можуть допомогти подолати пробіли в рядку.

scan(/\w+/).join видалить усі пробіли та приєднається до рядка

string = "White spaces in me".scan(/\w+/).join
=>"Whitespacesinme"

Це також вилучення місця в лівій і правій частині рядка. Значить ltrim, rtrimі trim. Про всяк випадок, якщо хтось передує C, FoxProабо Visual Basicзаскочить Ruby.

2.1.6 :002 > string = " White spaces in me ".scan(/\w+/).join => "Whitespacesinme" 2.1.6 :003 > string = " White spaces in me".scan(/\w+/).join => "Whitespacesinme" 2.1.6 :004 > string = "White spaces in me ".scan(/\w+/).join => "Whitespacesinme" 2.1.6 :005 >


1
@AmitPandya Дякую вам за вказівку додаткових ключових моментів методу .scan (). Вдячний !!!
Дхармеш Рупані


1

Я трохи запізнююся на гру, але я видаляю трейлінг та провідні пробіли за допомогою strip!. Якщо у вас є масив, як я, мені потрібно було повторити його і зберегти після закінчення екземпляра. The! подбав про це. Це вилучило всі пробіли в кінці або на початку, а не лише перший ведучий або останній кінець.

Наприклад:

array = ["hello ","   Melanie", "is", " new ", "to  ", " programming"]
array.each do |i|
  i.strip!
end

Це призведе до: ["привіт", "Меланія", "є", "новий", "до", "програмування"]. Далі я дослідив / поділився цим у відео, яке я зробив, щоб виділити цей код на подібне запитання .

Я новіший в програмуванні, і використання смуги не працювало, оскільки це не зберегло його в масив після закінчення циклу.


0

Ви можете спробувати це:

"ab c d efg hi ".split.map(&:strip)

щоб отримати це:

["ab, "c", "d", "efg", "hi"]

або якщо вам потрібна одна струна, просто використовуйте:

"ab c d efg hi ".split.join
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.