Chức năng Ruby để xóa tất cả các khoảng trắng?


573

Hàm Ruby để xóa tất cả các khoảng trắng là gì? Tôi đang tìm kiếm một cái gì đó giống như của PHP trim()?


36
Câu hỏi của bạn không rõ ràng: Bạn có muốn xóa tất cả các khoảng trắng hoặc bạn muốn thoát khỏi khoảng trắng hàng đầu và dấu?
Sinan Ünür

25
trim()Dải trắng của PHP " từ đầu và cuối chuỗi " (như đã nêu trong tài liệu ), nó không xóa "tất cả các khoảng trắng".
Tadeck

3
Khi nghi ngờ, hãy xem tài liệu trực tuyến của Ruby cho lớp String (xem .strip bên dưới).
Merovex

2
Lưu ý rằng tất cả các câu trả lời sử dụng String#striphoặc khớp /\s+/sẽ chỉ xóa khoảng trắng ASCII. Nếu bạn muốn đảm bảo bất kỳ khoảng trắng không phải ASCII nào cũng bị bắt (ví dụ: HTML &nbsp), hãy xem câu trả lời không phổ biến kỳ lạ từ @EBooker.
MatzFan

1
Đáng tiếc rằng những câu trả lời tuyệt vời như vậy không thể có được phẩm giá cuối cùng của một người được chấp nhận
New Alexandria

Câu trả lời:


846

Nếu bạn muốn xóa chỉ khoảng trắng hàng đầu và dấu (như trang trí của PHP), bạn có thể sử dụng .strip, nhưng nếu bạn muốn xóa tất cả khoảng trắng, bạn có thể sử dụng .gsub(/\s+/, "")thay thế.


5
Liệu "/ \ s + /" có nghĩa là khoảng trắng đơn giản?
Rails người mới bắt đầu

54
\ s + có nghĩa là 1 hoặc nhiều ký tự khoảng trắng (dấu cách, dòng mới, tab). // xung quanh cho thấy đó là một biểu thức chính quy.
dylanfm

3
Điều này không tương đương với trim ()
Brett Holt

6
dải là chính xác những gì tôi đang tìm kiếm, cảm ơn cho câu hỏi hay và awnser!
Francois

15
@BrettHolt Biểu thức gsub không giống như trim, nhưng người hỏi bao gồm cụm từ "tất cả khoảng trắng", cũng không giống như trim. Vì vậy, tôi đã đưa ra giải pháp thay thế.
joel.neely

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

Và để mô phỏng trim()chức năng của PHP :

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

12
Điều này dễ đọc hơn nhiều so với regex, tại sao nó không phổ biến?
ckarbass

89
@ckarbass: Bởi vì nhiều người thích các giải pháp quá phức tạp cho các vấn đề đơn giản. Nó đi xa với kinh nghiệm.
Ed S.

97
@ckarbass @Ed S. Nó không phổ biến vì nó không giống nhau. Câu hỏi ban đầu đã sử dụng cụm từ "tất cả khoảng trắng", bao gồm các tab, dòng mới, v.v ... Câu trả lời được đề xuất này sẽ không loại bỏ các ký tự khoảng trắng khác đó. Đối với "quá phức tạp", tôi khuyên bạn nên so sánh biểu thức chính quy đơn giản với .delete(' ').delete('\t').delete('\n') ..., quá dài dòng và cung cấp nhiều cơ hội cho lỗi chính tả và lỗi thiếu sót.
joel.neely

13
@ joel.neely: Tôi đã trả lời câu hỏi này từ lâu, nhưng đọc lại câu hỏi, lần này cẩn thận hơn. OP đã yêu cầu "một hàm để loại bỏ tất cả các khoảng trắng" , nhưng sau đó yêu cầu "một cái gì đó giống như trang trí của PHP ()" . Vì vậy, thật khó để biết chính xác những gì họ muốn ở đây. trim()chắc chắn không loại bỏ dòng mới và các ký tự khoảng trắng khác. Bạn đang chọn một cách giải thích cho một câu hỏi mơ hồ.
Ed S.

4
@ joel.neely: Điều đó nói rằng, tôi đồng ý rằng một giải pháp vượt ra ngoài cách giải thích theo nghĩa đen của câu hỏi là một giải pháp tốt hơn trong trường hợp này (nghĩa là một regex loại bỏ tất cả các ký tự sẽ tạo thành khoảng trắng thay vì một chuỗi các delete()cuộc gọi.)
Ed S.

163

Câu trả lời liên quan:

"   clean up my edges    ".strip

trả lại

"clean up my edges"

Đó là người tôi đã quên mất. Tôi biết có một phương pháp để loại bỏ khoảng trắng sẽ làm như vậy theo mặc định nếu không có đối số nào được thông qua. +1
Ed S.

Điều này tương đương với cắt. Vui lòng tham khảo trích dẫn từ @Tadeck ở trên.
Brett Holt

3
Nếu có khả năng là biến đó nil, hãy chắc chắn chạy .to_sphương thức trước khi chạy dải sao cho phương thức dải không gây ra lỗi. Ví dụ. str=nil; str.to_s.strip #=> ""
Scarver2

Tôi thích some_data.strip! nếu some_data.is_a? Chuỗi
slindsey3000

156

String#strip - loại bỏ tất cả khoảng trắng từ đầu và cuối.

String#lstrip - chỉ từ đầu.

String#rstrip - chỉ từ cuối.

String#chomp(không có đối số) - xóa dấu phân cách dòng ( \nhoặc \r\n) khỏi cuối.

String#chop - xóa ký tự cuối cùng.

String#delete- x.delete(" \t\r\n")- xóa tất cả các khoảng trắng được liệt kê.

String#gsub- x.gsub(/[[:space:]]/, '')- loại bỏ tất cả các khoảng trắng, bao gồm cả các unicode .


Lưu ý : Tất cả các phương thức trên trả về một chuỗi mới thay vì thay đổi gốc. Nếu bạn muốn thay đổi chuỗi tại chỗ, hãy gọi phương thức tương ứng !ở cuối.


Ví dụ xóa String # dường như sử dụng biểu thức chính quy, nhưng \snằm trong dấu ngoặc kép thay vì dấu gạch chéo. Ngoài ra tôi không thể tìm thấy bất kỳ đề cập nào trong tài liệu mà việc xóa có thể lấy regex làm đối số.
lười

@slothbear, nó không phải là regex, nó là một tập hợp nhỏ các mẫu tương tự như regex. Đối với các tài liệu #deleteđược cho là hoạt động tương tự #count. Bạn có thể thử nó trong giao diện điều khiển là tốt.
ndnenkov

Cảm ơn đã dạy tôi một cái gì đó mới. Và cũng cảm ơn lời nhắc để thử mọi thứ trong bối cảnh nhỏ nhất có thể (dòng lệnh).
lười

1
@SeinopSys Tôi chỉ muốn giữ câu trả lời này cho Ruby.
ndnenkov

2
Chỉ có ví dụ cuối cùng trong câu trả lời này mới bắt được ASCII 160 'không gian không phá vỡ', nguyên nhân của những kẻ phá hoại web. #stripkhông làm. Xem stackoverflow.com/questions/4859438/ khăn
MatzFan

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

Xóa công việc nhanh hơn =)

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
nhưng điều này chỉ xóa spaces, không phải tất cảwhite spaces
Gavriel

1
delete(" \t\r\n")sẽ chăm sóc khoảng trắng điển hình, và vẫn nhanh hơn gsub.
Seth Jeffery

94

Nếu bạn đang sử dụng Rails / ActiveSupport , bạn có thể sử dụng squishphương pháp. Nó loại bỏ khoảng trắng ở hai đầu của chuỗi và nhóm nhiều khoảng trắng thành không gian đơn.

Ví dụ.

" a  b  c ".squish

sẽ dẫn đến:

"a b c"

Kiểm tra tài liệu tham khảo này từ api.rubyonrails.org .


4
Lưu ý rằng các câu trả lời chỉ liên kết không được khuyến khích, các câu trả lời SO phải là điểm cuối của tìm kiếm giải pháp (so với một điểm dừng khác của tài liệu tham khảo, có xu hướng bị cũ theo thời gian). Vui lòng xem xét việc thêm một bản tóm tắt độc lập ở đây, giữ liên kết làm tài liệu tham khảo.
kleopatra

2
Tôi nghĩ rằng câu trả lời này đã được giải thích đủ và thực tế là liên kết là tham chiếu vì bản thân câu trả lời đã được giải thích rõ ràng. Chức năng này rất tốt, cảm ơn
ksugiarto

4
Đây là từ ActiveSupport. Bạn không cần tất cả các Rails để sử dụng nó, nhưng bạn cần ít nhất ActiveSupport và mộtrequire 'active_support/core_ext/string/filters'
Justin Force

2
Để rõ ràng, đây là bất kỳ khoảng trắng. Ví dụ:"a \t \n \f \r \v b".squish == "a b"
Purplejacket

47

Hơi muộn một chút, nhưng bất kỳ ai khác đang tìm kiếm trang này có thể quan tâm đến phiên bản này -

Nếu bạn muốn dọn sạch một đoạn văn bản được định dạng sẵn mà người dùng có thể đã cắt và dán vào ứng dụng của bạn bằng cách nào đó, nhưng vẫn giữ khoảng cách từ, hãy thử điều này:

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
Người ta cũng có thể sử dụng squishphương pháp của Rails : apidock.com/rails/String/squish
Phillip Koebbe

5
Hoặc nếu bạn không có Rails và bạn không có dòng mới, squeeze(" ")có thể hoạt động.
Andrew Grimm

45

.stripPhương thức của Ruby thực hiện PHP tương đương với trim().

Để xóa tất cả khoảng trắng:

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

@Tass làm cho tôi biết rằng câu trả lời ban đầu của tôi loại bỏ các chữ cái trùng lặp liên tiếp - Yucks! Tôi đã chuyển sang phương pháp squish thông minh hơn về các sự cố như vậy nếu sử dụng khung Rails.

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

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

Trích dẫn: http://apidock.com/rails/String/squish


1
Điều này sẽ loại bỏ các ký tự trùng lặp "đã tham gia". "good men".squeeze.stripsẽ trở lại"god men"
Tass

1
Cảm ơn đã chỉ ra rằng @Tass. Tôi đã chỉnh sửa câu trả lời của mình theo hướng có lợi cho phương pháp squish.
Scarver2

1
+1 cho "trùng lặp các chữ cái liên tiếp." Tôi không thể đưa ra một cách để mô tả kịch bản. Làm tốt! :-)
Tass

26
" Raheem Shaik ".strip

Nó sẽ loại bỏ không gian bên trái và bên phải. Mã này sẽ cung cấp cho chúng tôi:"Raheem Shaik"


20

Cũng đừng quên:

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

6
Vì vậy, s.split.join sẽ thực hiện công việc.
Piotr Brudny

1
Điều này thật tuyệt khi lặp đi lặp lại:[" Hello World", "Big Giraffe "].map(&:split).map(&:join) #=> ["HelloWorld", "BigGiraffe"]
tbloncar

20

split.join sẽ nổ tất cả các không gian bất cứ nơi nào trong chuỗi.

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

Thật dễ dàng để nhập và ghi nhớ, vì vậy nó rất hay trên bảng điều khiển và để hack nhanh. Có thể cho rằng không được hoan nghênh trong mã nghiêm trọng mặc dù nó che giấu ý định.

(Dựa trên nhận xét của Piotr trong câu trả lời của Justicle ở trên.)


1
Rất, rất cám ơn cho nhận xét này :-) Đây là phương pháp duy nhất hoạt động nếu bạn có chuỗi dài trông giống như một đoạn văn.
Boomerange

12

Bạn có thể thử cái này

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

bằng cách sử dụng : không gian: loại bỏ không gian không phá vỡ cùng với không gian thông thường.


1
Đây thực sự là câu trả lời tốt nhất IMHO, vì trong HTML hoang dã &nbspvà mọi khoảng trắng không phải ASCII khác sẽ không bị xóa String#striphoặc khớp bởi /\s/. Xem phần có tiêu đề "Biểu thức khung POSIX" trong tài liệu
Regapi

8

Sử dụng gsub hoặc xóa. Sự khác biệt là gsub có thể xóa các tab, trong khi xóa không thể. Đôi khi bạn có các tab trong các tệp được thêm bởi các biên tập viên.

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

Có nhiều cách:
Để xóa khoảng trắng từ cả hai phía:

Kiểu như trim của php ()

Foo_bar.strip

Để xóa tất cả các khoảng trắng:

Foo_bar.gsub(/ /, "")

Để xóa tất cả khoảng trắng:

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

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

nhưng điều này chỉ xóa spaces, không phải tất cảwhite spaces
Gavriel

6

Phương pháp gsub sẽ làm tốt.
Phương thức gsub có thể được gọi trên một chuỗi và nói:

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

Phương thức gsub tìm kiếm mọi lần xuất hiện của đối số thứ nhất và thay thế nó bằng đối số thứ hai. Trong trường hợp này, nó sẽ thay thế mọi khoảng trống trong chuỗi và loại bỏ nó.

Một vi dụ khac:

b = "the white fox has a torn tail"

Hãy thay thế mọi lần xuất hiện của chữ "t" bằng chữ "T"

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

5

Đối với hành vi khớp chính xác với PHP trim, phương pháp đơn giản nhất là sử dụng String#stripphương thức, như vậy:

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

Ruby cũng có một phiên bản chỉnh sửa tại chỗ, được gọi là String.strip!(lưu ý dấu vết '!'). Điều này không yêu cầu tạo một bản sao của chuỗi và có thể nhanh hơn đáng kể đối với một số mục đích sử dụng:

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

Cả hai phiên bản đều tạo ra đầu ra này:

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

Tôi đã tạo một điểm chuẩn để kiểm tra hiệu suất của một số sử dụng cơ bản stripstrip!, cũng như một số lựa chọn thay thế. Bài kiểm tra này là:

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

Đây là kết quả:

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

Sở thích cá nhân của tôi là sử dụng phương pháp .tr

như trong:

string = "this is a string to smash together"

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

Cảm ơn @FrankScmitt đã chỉ ra rằng để thực hiện xóa tất cả khoảng trắng (không chỉ khoảng trắng), bạn sẽ cần phải viết nó như sau:

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

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

nhưng điều này chỉ xóa spaces, chứ không phảiall white spaces
Gavriel

Để xóa tất cả các khoảng trắng (dấu cách, tab, dòng mới), hãy xem xét sử dụng s.tr(" \t\n", '')thay thế.
Frank Schmitt

@Gavriel - Tôi đã đọc sai / hiểu sai câu hỏi, cảm ơn bạn đã chỉ ra điều đó.
Jeremy Gunter

@FrankSchmitt Tôi đã thêm phần sửa lỗi của bạn vào câu trả lời của tôi, để trả lời đúng hơn câu hỏi của OP. Cảm ơn bạn đã sửa chữa cho tôi.
Jeremy Gunter

3

Tôi đã cố gắng làm điều này vì tôi muốn sử dụng một "tiêu đề" hồ sơ như một id trong chế độ xem nhưng các tiêu đề có khoảng trắng.

một giải pháp là:

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

1

Ruby .scan().join()các phương thức của String cũng có thể giúp khắc phục khoảng trắng trong chuỗi.

scan(/\w+/).join sẽ xóa tất cả các khoảng trắng và tham gia chuỗi

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

Nó cũng loại bỏ không gian từ phần bên trái và bên phải của chuỗi. Có nghĩa là ltrim, rtrimtrim. Chỉ trong trường hợp nếu ai đó có nền tảng C, FoxProhoặc Visual Basicnhảy vào 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 Cảm ơn bạn rất nhiều vì đã chỉ ra các điểm chính bổ sung của phương thức .scan (). Đánh giá cao !!!
Dharmesh Rupani

1

Tôi sẽ sử dụng một cái gì đó như thế này:

my_string = "Foo bar\nbaz quux"

my_string.split.join
=> "Foobarbazquux"

thẳng về phía trước. Cảm ơn
srikanth peetha

1

Tôi hơi trễ trò chơi, nhưng tôi loại bỏ dấu vết và dẫn đầu khoảng trắng bằng cách sử dụng strip!. Nếu bạn có một mảng, chẳng hạn như tôi đã làm, tôi cần lặp lại qua mảng và lưu nó sau khi thể hiện kết thúc. Các ! đã chăm sóc điều này. Điều này đã loại bỏ tất cả các khoảng trắng ở cuối hoặc đầu, không chỉ dẫn đầu tiên hoặc cuối cùng.

Ví dụ:

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

Điều này sẽ xuất ra: ["xin chào", "Melanie", "là", "mới", "đến", "lập trình"]. Tôi đã khám phá thêm / chia sẻ điều này trong một video tôi làm để làm nổi bật mã này cho câu hỏi tương tự mà tôi có .

Tôi mới hơn để lập trình và sử dụng dải không hoạt động vì nó không lưu nó vào mảng sau khi vòng lặp kết thúc.


0

Bạn có thể thử điều này:

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

để có được điều này:

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

hoặc nếu bạn muốn một chuỗi đơn, chỉ cần sử dụng:

"ab c d efg hi ".split.join
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.