Tüm beyaz boşlukları kaldırmak için Ruby işlevi?


573

Tüm beyaz boşlukları kaldırmak için Ruby işlevi nedir ? Ben PHP gibi bir şey trim()mi arıyorsunuz?


36
Sorunuz açık değil: Tüm boşlukları kaldırmak mı yoksa önde gelen ve sondaki boşluklardan kurtulmak mı istiyorsunuz?
Sinan Ünür

25
PHP'nin trim()boşlukları " bir dizginin başından ve sonundan " çıkarır ( belgelerde belirtildiği gibi ), "tüm boşlukları" kaldırmaz.
Tadeck

3
Şüphe duyduğunuzda, String sınıfı için Ruby çevrimiçi belgelerine bakın (aşağıdaki .strip dosyasına bakın).
Merovex

2
String#stripEşleştirme veya eşleştirme kullanan tüm yanıtların /\s+/yalnızca ASCII boşluğunu kaldıracağını unutmayın. ASCII olmayan boşlukların da yakalandığından emin olmak istiyorsanız (örn. HTML'ler &nbsp) @EBooker'dan tuhaf derecede popüler olmayan yanıta bakın.
MatzFan

1
Yazık ki böyle büyük cevaplar kabul edilen kişinin son haysiyetini alamaz
New Alexandria

Yanıtlar:


846

Yalnızca önde gelen ve sondaki boşlukları (PHP'nin kırpması gibi) .stripkaldırmak istiyorsanız kullanabilirsiniz , ancak tüm boşlukları kaldırmak istiyorsanız .gsub(/\s+/, "")bunun yerine kullanabilirsiniz .


5
"/ \ S + /" basit boşluk anlamına mı gelir?
Raylar acemi

54
\ s +, 1 veya daha fazla boşluk karakteri (boşluk, yeni satır, sekme) anlamına gelir. // çevreleyen, bunun normal bir ifade olduğunu gösterir.
dylanfm

3
Bu trim () ile eşdeğer değildir
Brett Holt

6
şerit tam olarak ne aradığını, iyi soru ve awnser için teşekkürler!
Francois

15
@BrettHolt gsub ifadesi trim ile aynı değildir, ancak sorgulayan kişi trim ile aynı olmayan "all whitespace" ifadesini de içerir. Bu yüzden alternatifler verdim.
joel.neely

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

Ve PHP'nin trim()işlevini taklit etmek için :

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

12
bu normal ifadeden çok daha okunabilir, neden bu kadar popüler değil?
ckarbass

89
@ckarbass: Çünkü birçok insan basit sorunlara aşırı karmaşık çözümleri tercih ediyor. Tecrübe ile ortadan kalkar.
Ed

97
@ckarbass @Ed S. Aynı değil çünkü popüler değil. Orijinal soru, sekmeler, yeni satırlar vb. İçeren "tüm boşluk" ifadesini kullandı. Bu önerilen yanıt, diğer boşluk karakterlerini kaldırmayacaktır. "Aşırı karmaşık" a gelince, aşırı düzenli .delete(' ').delete('\t').delete('\n') ...ve yazım hataları ve ihmal hataları için birçok fırsat sağlayan basit düzenli ifadeyi karşılaştırmanızı öneririm .
joel.neely

13
@ joel.neely: Bu soruyu uzun zaman önce yanıtladım, ancak bu kez daha dikkatli bir şekilde tekrar okuyun. OP "tüm boşlukları kaldırmak için bir fonksiyon" istedi, ama sonra "PHP'nin trim ()" gibi bir şey istedi . Burada tam olarak ne istediklerini bilmek biraz zor. trim()kesinlikle satırsonu ve diğer boşluk karakterlerini kaldırmaz. Belirsiz bir sorunun tek bir yorumunu seçiyorsunuz.
Ed S.

4
@ joel.neely: Ben sorunun literal yorumlanması ötesinde bir çözüm bu durumda daha iyi biri olduğunu kabul söyledi (yani boşluk yerine bir dize daha teşkil edeceğini tüm karakterleri kaldırarak regex delete()aramalar.)
Ed S.

163

İlgili cevap:

"   clean up my edges    ".strip

İadeler

"clean up my edges"

Bunu unuttum. Herhangi bir argüman geçirilmemişse, varsayılan olarak bunu yapacak olan boşlukları kaldırmak için bir yöntem olduğunu biliyordum. +1
Ed

Bu kırpmaya eşdeğerdir. Lütfen yukarıdaki @Teck'ten alıntıya bakın.
Brett Holt

3
Değişkenin olması ihtimali varsa, şeridi nilçalıştırmadan .to_sönce yöntemi kullandığınızdan emin olun, böylece şerit yöntemi bir hata oluşturmaz. Ör. str=nil; str.to_s.strip #=> ""
scarver2

Some_data.strip'i tercih ederim! some_data.is_a? String
slindsey3000

156

String#strip - tüm boşlukları baştan ve sondan kaldırın.

String#lstrip - en başından beri.

String#rstrip - sadece sondan.

String#chomp(bağımsız değişken olmadan) - satır ayırıcıları ( \nveya \r\n) sondan siler .

String#chop - son karakteri siler.

String#delete- x.delete(" \t\r\n")- listelenen tüm boşlukları siler.

String#gsub- x.gsub(/[[:space:]]/, '')- unicode olanlar dahil tüm boşlukları kaldırır .


Not : Yukarıdaki tüm yöntemler, orijinali değiştirmek yerine yeni bir dize döndürür. Dizeyi yerinde değiştirmek istiyorsanız !, sonunda ilgili yöntemi ile çağırın .


String # delete örneği normal ifade kullanıyor gibi görünüyor, ancak \seğik çizgiler yerine tırnak işaretleri içinde. Ayrıca, silme işleminin argüman olarak normal ifadeyi alabileceği belgelerinde herhangi bir söz bulamadım.
slothbear

@slothbear, bu bir normal ifade değil, normal ifadelere benzeyen küçük bir desen seti. Belgelere gelince #deletebenzer şekilde çalıştığı söyleniyor #count. Konsolda da deneyebilirsiniz.
ndnenkov

Bana yeni bir şey öğrettiğiniz için teşekkürler. Ayrıca, hatırlatma için işleri mümkün olan en küçük bağlamda (komut satırı) denemeniz için teşekkür ederiz.
slothbear

1
@SeinopSys Bu cevabı sadece Ruby'de tutmak istedim.
ndnenkov

2
Sadece bu cevaptaki son örnek, korkunç kazıcı ASCII 160 'kırılmayan alanı', web kazıyıcıların bantasını yakalar. #stripdeğil. Bkz. Stackoverflow.com/questions/4859438/…
MatzFan

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

Silme daha hızlı çalışır =)

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
ama bu sadece spaceshepsini kaldırıyorwhite spaces
Gavriel

1
delete(" \t\r\n")tipik boşlukla ilgilenir ve hala gsub'dan daha hızlıdır.
Seth Jeffery

94

Rails / ActiveSupport kullanıyorsanız , aşağıdakileri kullanabilirsiniz:squish yöntemi . Dizenin her iki ucundaki beyaz boşluğu kaldırır ve birden çok beyaz boşluğu tek boşluk olarak gruplandırır.

Örneğin.

" a  b  c ".squish

aşağıdakilerle sonuçlanır:

"a b c"

Bu referansı api.rubyonrails.org adresinden kontrol edin .


4
Not o bağlantı sadece cevaplar tavsiye edilmez, SO cevaplar çözüm (vs. henüz zamanla bayat almak eğilimindedir referanslar, başka mola) için bir aramanın son nokta olmalıdır. Lütfen bağlantıyı referans olarak tutarak bağımsız bir özet eklemeyi düşünün.
Kleopatra

2
Bence bu cevap yeterince açıklanmıştı ve cevabın kendisi netleştiği için bağlantının referans olduğu gerçeği açıklanmıştı. Bu işlev iyiydi, teşekkürler
ksugiarto

4
Bu ActiveSupport'tan. Kullanmak için tüm Rails'e ihtiyacınız yoktur, ancak en azından ActiveSupport'a ve birrequire 'active_support/core_ext/string/filters'
Justin Force

2
Açık olmak gerekirse, bu herhangi bir boşluk. Ör."a \t \n \f \r \v b".squish == "a b"
Purplejacket

47

Biraz geç oldu, ancak bu sayfayı ziyaret eden herkes bu sürümle ilgilenebilir -

Bir kullanıcının uygulamanıza bir şekilde kesip yapıştırabileceği önceden biçimlendirilmiş bir metin grubunu temizlemek, ancak kelime aralığını korumak istiyorsanız şunu deneyin:

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
Bir Rails squishyöntemi de kullanılabilir : apidock.com/rails/String/squish
Phillip Koebbe

5
Veya Rails'iniz yoksa ve yeni satırlarınız yoksa squeeze(" ")işe yarayabilir.
Andrew Grimm

45

Ruby'nin .stripyöntemi PHP'ye eşdeğerdir trim().

Tüm boşlukları kaldırmak için:

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

@Tass, orijinal cevabımın yinelenen harfleri art arda kaldırdığını fark etti - YUCK! O zamandan beri Rails çerçevesini kullanıyorsanız bu tür olaylar hakkında daha akıllı olan squish yöntemine geçtim.

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

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

Alıntı: http://apidock.com/rails/String/squish


1
Bu, "birleştirilmiş" yinelenen karakterleri kaldıracaktır. "good men".squeeze.stripgeri dönecek"god men"
Tass

1
@Tass'a işaret ettiğin için teşekkürler. Cevabımı ezme yöntemi lehine düzenledim.
scarver2

1
+1 "art arda yinelenen harfler" için. Senaryoyu tanımlamanın bir yolunu bulamadım. Aferin! :-)
Tass

26
" Raheem Shaik ".strip

Sol ve sağ yan boşlukları kaldıracaktır. Bu kod bize şunu verir:"Raheem Shaik"


20

Ayrıca unutmayın:

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

6
Yani s.split.join işi yapacak.
Piotr Brudny

1
[" Hello World", "Big Giraffe "].map(&:split).map(&:join) #=> ["HelloWorld", "BigGiraffe"]
Tekrarlarken

20

split.join dizenin herhangi bir yerindeki tüm boşlukları patlatacaktır.

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

Yazması ve hatırlaması kolaydır, bu yüzden konsolda ve hızlı saldırı için iyidir. Niyetini maskelediği için tartışmasız ciddi kodda hoş karşılanmıyor.

( Piotr'un yukarıdaki Justicle cevabındaki yorumuna dayanarak .)


1
Bu yorum için çok, çok teşekkürler :-) Bu, bir paragrafa benzeyen uzun bir dizeniz varsa çalışan tek yöntemdir.
Boomerange

12

Bunu deneyebilirsin

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

using : space: normal alanla birlikte kırılmayan alanı kaldırır.


1
Bu aslında vahşi HTML'de olduğu gibi en iyi cevap IMHO &nbsp ve başka herhangi bir ASCII olmayan beyaz alanlara olacak değil tarafından kaldırılabilir String#stripya eşleşmesi /\s/.
Regexp

8

Gsub kullanın veya silin. Fark gsub sekmeleri kaldırabilir, ancak silemez. Bazen editörler tarafından eklenen dosyalarda sekmeler bulunur.

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

Birçok yol vardır:
Boşluğu her iki taraftan kaldırmak için:

Php's trim () gibi

Foo_bar.strip

Tüm boşlukları kaldırmak için:

Foo_bar.gsub(/ /, "")

Tüm boşlukları kaldırmak için:

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

6
"asd sda sda sd".gsub(' ', '')
=> "asdsdasdasd"

ama bu sadece spaceshepsini kaldırıyorwhite spaces
Gavriel

6

Gsub yöntemi gayet iyi olacak.
Bir dizede gsub yöntemi çağrılabilir ve şöyle der:

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

Gsub yöntemi, ilk bağımsız değişkenin her örneğini arar ve ikinci bağımsız değişkenle değiştirir. Bu durumda, dize içindeki her boşluğun yerini alacak ve onu kaldıracaktır.

Başka bir örnek:

b = "the white fox has a torn tail"

"T" harfinin her tekrarını büyük "T" harfiyle değiştirelim

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

5

PHP ile tam olarak eşleşen davranışlar için trim, en basit yöntem şu şekilde String#stripyöntemi kullanmaktır :

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

Ruby'nin yerinde düzenleme de var String.strip!( denilen '!' Karakterine dikkat edin). Bu, dizenin bir kopyasını oluşturmayı gerektirmez ve bazı kullanımlar için önemli ölçüde daha hızlı olabilir:

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

Her iki sürüm de bu çıktıyı üretir:

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

Ben bazı temel kullanımları performansını test etmek için bir kriter oluşturdu stripve strip!iyi bazı alternatifler kadar. Test şudur:

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

Bunlar sonuçlar:

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

Kişisel tercihim yöntemi kullanmak .tr

de olduğu gibi:

string = "this is a string to smash together"

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

@FrankScmitt sayesinde bunun tüm boşlukları (sadece boşlukları değil) silmesini sağlamak için işaret etmelisiniz :

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

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

ama bu sadece kaldırır spaces, değilall white spaces
Gavriel

Tüm beyaz boşlukları (boşluk, sekme, yeni satır) kaldırmak için s.tr(" \t\n", '')bunun yerine kullanmayı düşünün .
Frank Schmitt

@Gavriel - Soruyu yanlış okudum / yanlış anladım, belirttiğiniz için teşekkür ederim.
Jeremy Gunter

@FrankSchmitt OP'nin sorusunu daha doğru bir şekilde cevaplamak için düzeltmeye cevabımı ekledim. Beni doğruladığınız için teşekkür ederim.
Jeremy Gunter

3

Ben bir kayıt "başlık" görünümünde bir kimlik olarak kullanmak istedim ama başlıklar boşluk vardı bunu yapmaya çalışıyordu.

bir çözüm:

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

1

Ruby .scan()ve .join()String metotları da string içindeki boşlukların üstesinden gelmeye yardımcı olabilir.

scan(/\w+/).join tüm boşlukları kaldıracak ve dizeye katılacak

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

Ayrıca, dizenin sol ve sağ kısmından boşluk kaldırıyor. Means ltrim, rtrimve trim. Her ihtimale karşı birisi üzerinde bulunduğu arka planı varsa C, FoxProya da Visual Basicve atlamak 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 () yönteminin ek anahtar noktalarını işaretlediğiniz için çok teşekkür ederiz. Takdir !!!
Dharmesh Rupani


1

Oyuna biraz geç kaldım, ama sondaki boşlukları ve boşlukları kullanarak kaldırıyorum strip!. Benim yaptığım gibi bir dizi varsa, dizi üzerinden yineleme ve örnek sona erdikten sonra kaydetmek gerekiyordu. ! bununla ilgileniyordu. Bu, yalnızca ilk satır veya son satır değil, sondaki veya başlangıçtaki tüm boşluk alanlarını kaldırdı.

Örneğin:

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

Bu şu şekilde sonuçlanır: ["merhaba", "Melanie", "", "yeni", "ila", "programlama"]. Ben de benzer bir soru vardı bu kodu vurgulamak için yaptığım bir videoda bu araştırdı / paylaştı .

Döngü bittikten sonra diziye kaydetmediği için programlama ve şerit kullanma konusunda daha yeni değilim.


0

Bunu deneyebilirsiniz:

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

Bunu elde etmek için:

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

veya tek bir dize istiyorsanız, şunu kullanın:

"ab c d efg hi ".split.join
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.