Funkcja Ruby, aby usunąć wszystkie białe spacje?


573

Jaka jest funkcja Ruby, aby usunąć wszystkie białe spacje? Szukam czegoś w rodzaju PHP trim()?


36
Twoje pytanie nie jest jasne: czy chcesz usunąć wszystkie białe znaki, czy chcesz pozbyć się początkowych i końcowych białych znaków?
Sinan Ünür

25
PHP trim()usuwa białe znaki „ od początku i końca łańcucha ” (jak podano w dokumentacji ), nie usuwa „wszystkich białych znaków”.
Tadeck

3
W razie wątpliwości zajrzyj do dokumentacji online Ruby dla klasy String (patrz .strip poniżej).
Merovex

2
Pamiętaj, że wszystkie odpowiedzi wykorzystujące String#striplub dopasowujące /\s+/usuwają tylko białe znaki ASCII. Jeśli chcesz się upewnić, że wszystkie białe znaki spoza ASCII są przechwytywane (np. HTML &nbsp), zobacz dziwnie niepopularną odpowiedź @EBooker.
MatzFan,

1
Szkoda, że ​​tak wspaniałe odpowiedzi nie mogą uzyskać ostatecznej godności akceptacji
Nowa Aleksandria

Odpowiedzi:


846

Jeśli chcesz usunąć tylko wiodące i końcowe białe spacje (jak przycinanie PHP), możesz użyć .strip, ale jeśli chcesz usunąć wszystkie białe spacje, możesz użyć .gsub(/\s+/, "")zamiast tego.


5
Czy proste „/ \ s + /” oznacza białe spacje?
Początkujący Rails

54
\ s + oznacza 1 lub więcej białych znaków (spacja, nowa linia, tabulator). // otaczające pokazuje, że jest to wyrażenie regularne.
dylanfm

3
Nie jest to równoważne z trim ()
Brett Holt

6
strip był dokładnie tym, czego szukałem, dzięki za dobre pytanie i fajne!
Francois

15
@BrettHolt Wyrażenie gsub nie jest tym samym co trim, ale pytający zawarł frazę „all white space”, która również nie jest tym samym co trim. Dałem więc alternatywy.
joel.neely

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

Aby emulować trim()funkcję PHP :

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

12
jest to o wiele bardziej czytelne niż regex, dlaczego nie jest tak popularne?
ckarbass,

89
@ckarbass: Ponieważ wiele osób woli zbyt skomplikowane rozwiązania prostych problemów. Odchodzi z doświadczeniem.
Ed S.,

97
@ckarbass @Ed S. Nie jest tak popularny, ponieważ nie jest taki sam. W pierwotnym pytaniu użyto wyrażenia „wszystkie białe znaki”, które obejmuje tabulatory, znaki nowej linii itp. Ta proponowana odpowiedź nie usunie innych znaków białych znaków. Jeśli chodzi o „zbyt skomplikowane”, proponuję porównać proste wyrażenie regularne .delete(' ').delete('\t').delete('\n') ..., które jest zbyt szczegółowe i zapewnia wiele możliwości literówek i błędów pominięcia.
joel.neely

13
@ joel.neely: Odpowiedziałem na to pytanie dawno temu, ale przeczytałem je jeszcze raz, tym razem ostrożniej. OP poprosił o „funkcję usuwania wszystkich białych znaków” , ale następnie poprosił o „coś w stylu PHP trim ()” . Trudno więc dokładnie wiedzieć, czego chcą tutaj. trim()z pewnością nie usuwa znaków nowej linii i innych białych znaków. Wybieracie jedną interpretację niejasnego pytania.
Ed S.

4
@ joel.neely: To powiedziawszy, zgadzam się, że rozwiązanie, które wykracza poza dosłowną interpretację pytania, jest lepsze w tym przypadku (tj. wyrażenie regularne usuwające wszystkie znaki, które tworzyłyby spacje, a nie ciąg delete()wezwań.)
Ed S.

163

Powiązana odpowiedź:

"   clean up my edges    ".strip

zwroty

"clean up my edges"

O tym zapomniałem. Wiedziałem, że istnieje metoda usuwania białych znaków, która zrobiłaby to domyślnie, gdyby nie podano żadnych argumentów. +1
wyd S.

Jest to równoważne z przycinaniem. Proszę zapoznać się z cytatem z @Tadeck powyżej.
Brett Holt

3
Jeśli istnieje możliwość, że zmienna jest nil, należy uruchomić .to_smetodę przed uruchomieniem paska, aby metoda paska nie spowodowała błędu. Dawny. str=nil; str.to_s.strip #=> ""
scarver2

Wolę some_data.strip! jeśli some_data.is_a? String
slindsey3000

156

String#strip - usuń wszystkie białe znaki od początku i na końcu.

String#lstrip - od samego początku.

String#rstrip - tylko od końca.

String#chomp(bez argumentów) - usuwa separatory linii ( \nlub \r\n) od końca.

String#chop - usuwa ostatni znak.

String#delete- x.delete(" \t\r\n")- usuwa wszystkie wymienione białe znaki.

String#gsub- x.gsub(/[[:space:]]/, '')- usuwa wszystkie białe znaki, w tym znaki Unicode .


Uwaga : Wszystkie powyższe metody zwracają nowy ciąg zamiast mutować oryginał. Jeśli chcesz zmienić ciąg na miejscu, wywołaj odpowiednią metodę !na końcu.


Przykład ciąg # usuń wydaje się używać wyrażenia regularnego, ale \sjest w cudzysłowie zamiast ukośników. Nie mogłem również znaleźć żadnej wzmianki w dokumentacji, że usunięcie może przyjąć wyrażenie regularne jako argument.
Wargacz leniwy

@ slothbear, to nie jest wyrażenie regularne, to mały zestaw wzorów, które przypominają wyrażenia regularne. Jeśli chodzi o dokumentację, #deletemówi się, że działa podobnie do #count. Możesz spróbować również w konsoli.
ndnenkov

Dzięki za nauczenie mnie czegoś nowego. A także dzięki za przypomnienie, aby wypróbować rzeczy w najmniejszym możliwym kontekście (linia poleceń).
leniwiec

1
@SeinopSys Chciałem zachować tę odpowiedź tylko dla Ruby.
ndnenkov

2
Tylko ostatni przykład w tej odpowiedzi uchwyca przerażającą ASCII 160 „przestrzeń niezniszczalną”, zmorę zgarniaczy wstęgi. #stripnie. Zobacz stackoverflow.com/questions/4859438/...
MatzFan

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

Usuń działa szybciej =)

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
ale to usuwa tylko spaces, nie wszystkowhite spaces
Gavriel

1
delete(" \t\r\n")zajmie się typowymi białymi spacjami i nadal jest szybszy niż gsub.
Seth Jeffery

94

Jeśli używasz Rails / ActiveSupport , możesz użyć squishmetody. Usuwa białe spacje na obu końcach łańcucha i grupuje wiele białych spacji w pojedyncze spacje.

Na przykład

" a  b  c ".squish

spowoduje:

"a b c"

Sprawdź to odniesienie na api.rubyonrails.org .


4
Zauważ, że łącza tylko odpowiedzi są zniechęceni, SO odpowiedzi powinny być końcowy punkt w poszukiwaniu rozwiązania (w porównaniu z kolejnym postoju odniesień, które mają tendencję do dostać nieświeże w czasie). Rozważ dodanie tutaj autonomicznego streszczenia, zachowując link jako odniesienie.
Kleopatra

2
Myślę, że ta odpowiedź była wystarczająco wyjaśniona, a fakt, że link był odnośnikiem, ponieważ sama odpowiedź była jasno wyjaśniona. Ta funkcja była dobra, dzięki
ksugiarto,

4
To pochodzi z ActiveSupport. Nie potrzebujesz wszystkich Railsów, aby z niego korzystać, ale potrzebujesz przynajmniej ActiveSupport irequire 'active_support/core_ext/string/filters'
Justin Force

2
Żeby było jasne, to dowolna biała spacja. Np."a \t \n \f \r \v b".squish == "a b"
Purplejacket

47

Jest trochę późno, ale każda inna osoba googlująca na tej stronie może być zainteresowana tą wersją -

Jeśli chcesz wyczyścić fragment wstępnie sformatowanego tekstu, który użytkownik mógł w jakiś sposób wyciąć i wkleić w aplikacji, ale zachowaj odstępy między słowami, spróbuj wykonać następujące czynności:

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
Można również użyć szyn squishMetoda: apidock.com/rails/String/squish
Phillip Koebbe

5
Lub jeśli nie masz Railsów i nie masz nowych linii, squeeze(" ")może działać.
Andrew Grimm,

45

.stripMetoda Ruby wykonuje odpowiednik PHP trim().

Aby usunąć wszystkie białe znaki:

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

@Tass uświadomił mi, że moja oryginalna odpowiedź usuwa zduplikowane litery po kolei - FUCK! Od tego czasu przeszedłem na metodę squish, która jest mądrzejsza w takich przypadkach, jeśli używasz frameworka Rails.

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

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

Cite: http://apidock.com/rails/String/squish


1
Spowoduje to usunięcie „połączone” duplikat znaków. "good men".squeeze.strippowróci"god men"
Tass

1
Dziękujemy za zwrócenie uwagi na @Tass. Zredagowałem swoją odpowiedź na korzyść metody squisha.
scarver2

1
+1 za „zduplikowane litery po kolei”. Nie mogłem znaleźć sposobu na opisanie tego scenariusza. Dobra robota! :-)
Tass

26
" Raheem Shaik ".strip

Usunie spacje po lewej i prawej stronie. Ten kod dałby nam:"Raheem Shaik"


20

Nie zapomnij też:

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

6
Więc s.split.join wykona zadanie.
Piotr Brudny

1
Jest to miłe, gdy [" Hello World", "Big Giraffe "].map(&:split).map(&:join) #=> ["HelloWorld", "BigGiraffe"]
iterujemy

20

split.join wysadzi wszystkie spacje w dowolnym miejscu ciągu.

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

Łatwo jest pisać i zapamiętywać, więc jest przyjemny dla konsoli i do szybkiego hakowania. Prawdopodobnie nie jest mile widziany w poważnym kodzie, ponieważ maskuje to zamiar.

(Na podstawie komentarza Piotra w odpowiedzi Justicle powyżej.)


1
Bardzo dziękuję za ten komentarz :-) To jedyna metoda, która działa, jeśli masz długi ciąg znaków, który wygląda jak akapit.
Boomerange

12

Możesz spróbować tego

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

using : space: usuwa spacje nierozdzielające wraz ze zwykłym spacją.


1
To jest właściwie najlepsza odpowiedź IMHO, ponieważ w dzikim HTML &nbspi inne białe znaki spoza ASCII nie zostaną usunięte String#stripani dopasowane przez /\s/. Zobacz sekcję „Wyrażenia nawiasów POSIX” w dokumentach
Regexp

8

Użyj gsub lub usuń. Różnica polega na tym, że gsub może usuwać karty, podczas gdy usuwanie nie. Czasami masz zakładki w plikach, które są dodawane przez redaktorów.

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

Istnieje wiele sposobów:
Aby usunąć białe znaki z obu stron:

Coś w stylu trymowania php ()

Foo_bar.strip

Aby usunąć wszystkie spacje:

Foo_bar.gsub(/ /, "")

Aby usunąć wszystkie białe znaki:

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

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

ale to usuwa tylko spacesnie wszystkiewhite spaces
Gavriel

6

Metoda gsub wystarczy.
Metodę gsub można wywołać na łańcuchu i mówi:

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

Metoda gsub wyszukuje każde wystąpienie pierwszego argumentu i zastępuje go drugim argumentem. W takim przypadku zastąpi każdą spację w ciągu i usunie ją.

Inny przykład:

b = "the white fox has a torn tail"

Zastąpmy każde wystąpienie litery „t” wielką literą „T”

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

5

Aby zachowanie dokładnie pasowało do PHP trim, najprostszą metodą jest użycie tej String#stripmetody:

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

Ruby ma również wersję do edycji na miejscu, zwaną String.strip!(zwróć uwagę na końcowe „!”). Nie wymaga to tworzenia kopii ciągu i może być znacznie szybsze w przypadku niektórych zastosowań:

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

Obie wersje generują następujące dane wyjściowe:

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

Stworzyłem punkt odniesienia, aby przetestować wydajność niektórych podstawowych zastosowań stripi strip!, a także niektórych alternatyw. Test jest następujący:

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

Oto wyniki:

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

Moje osobiste preferencje to stosowanie tej metody .tr

jak w:

string = "this is a string to smash together"

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

Dzięki @FrankScmitt za zwrócenie uwagi, że aby usunąć wszystkie białe znaki (nie tylko spacje), musisz napisać to w ten sposób:

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

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

ale to usuwa tylko spaces, nieall white spaces
Gavriel

Aby usunąć wszystkie białe spacje (spację, tabulator, znak nowej linii), rozważ użycie s.tr(" \t\n", '')zamiast tego.
Frank Schmitt,

@Gavriel - źle odczytałem / źle zrozumiałem pytanie, dziękuję za zwrócenie na to uwagi.
Jeremy Gunter,

@FrankSchmitt Dodałem twoją poprawkę do mojej odpowiedzi, aby bardziej poprawnie odpowiedzieć na pytanie PO. Dziękuję za poprawienie mnie.
Jeremy Gunter,

3

Próbowałem to zrobić, ponieważ chciałem użyć „tytułu” jako identyfikatora w widoku, ale tytuły miały spacje.

rozwiązaniem jest:

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

1

Ruby .scan()i .join()metody String mogą również pomóc pokonać białe znaki w łańcuchu.

scan(/\w+/).join usunie wszystkie spacje i połączy łańcuch

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

Usuwa również spację z lewej i prawej części łańcucha. Środki ltrim, rtrimi trim. Tylko w przypadku, jeśli ktoś ma na tło C, FoxProalbo Visual Basici skakać 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 Dziękuję bardzo za wskazanie dodatkowych kluczowych punktów metody .scan (). Doceniany !!!
Dharmesh Rupani


1

Jestem trochę spóźniony do gry, ale usuwam końcowe i białe znaki za pomocą strip!. Jeśli masz tablicę, taką jak ja, musiałem iterować ją i zapisać po zakończeniu instancji. The! zająłem się tym. Spowodowało to usunięcie wszystkich białych znaków na końcu lub na początku, a nie tylko pierwszego wiodącego lub ostatniego końcowego.

Na przykład:

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

Spowoduje to wyprowadzenie do: [„hello”, „Melanie”, „is”, „new”, „to”, „programowanie”]. Następnie zbadałem / udostępniłem to w filmie, który nakręciłem, aby podkreślić ten kod w przypadku podobnego pytania .

Jestem nowszy w programowaniu i używanie paska nie działało, ponieważ nie zapisało go w tablicy po zakończeniu pętli.


0

Możesz spróbować:

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

aby to uzyskać:

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

lub jeśli chcesz pojedynczy ciąg, po prostu użyj:

"ab c d efg hi ".split.join
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.