2011-01-11 35 views
26

Tôi không chắc chắn cách làm như thế này, vì tôi khá mới đối với cụm từ thông dụng và dường như không tìm được phương pháp thích hợp để thực hiện điều này. chuỗi (tất cả các tab và các dòng mới được bao gồm)Ruby giảm tất cả khoảng trắng thành không gian đơn

1/2 cup 




      onion   
      (chopped) 

Làm cách nào để loại bỏ tất cả khoảng trắng và thay thế mỗi cá thể chỉ bằng một dấu cách?

Trả lời

53

Đây là một trường hợp biểu thức thông thường làm việc tốt, bởi vì bạn muốn đối xử với cả lớp ký tự khoảng trắng giống nhau và thay thế chạy của bất kỳ sự kết hợp của khoảng trắng với một ký tự không gian đơn. Vì vậy, nếu chuỗi được lưu trữ trong s, sau đó bạn sẽ làm gì:

fixed_string = s.gsub(/\s+/, ' ') 
+1

Đây là câu trả lời đúng và một tên đẹp, tôi có thể thêm . :) –

8

Bạn muốn phương pháp bóp:

str.squeeze([other_str]*) → new_str 
Builds a set of characters from the other_str parameter(s) using the procedure described for String#count. Returns a new string where runs of the same character that occur in this set are replaced by a single character. If no arguments are given, all runs of identical characters are replaced by a single character. 

    "yellow moon".squeeze     #=> "yelow mon" 
    " now is the".squeeze(" ")   #=> " now is the" 
    "putters shoot balls".squeeze("m-z") #=> "puters shot balls" 
+1

Điều này là không đúng, tôi nghĩ vậy. Nó sẽ chỉ nén các tab chạy vào một tab duy nhất và chạy các dòng mới thành một dòng mới. Khi tôi đọc nó, câu hỏi đang tìm kiếm một cách để thay thế chạy của bất kỳ sự kết hợp của các ký tự khoảng trắng với một nhân vật không gian duy nhất. – Chuck

+0

Quá xấu 'String.squeeze' không chấp nhận regex làm đối số. Upvote nếu bạn nghĩ rằng đó sẽ là một ý tưởng tốt; Tôi có thể gửi PR. – the911s

+2

cũng điều này sẽ loại bỏ trùng lặp, ví dụ: "class" trở thành "clas", mà có thể là một breaker thỏa thuận nếu chạy điều này trên html nói, phương pháp thích hợp hơn (nếu trong đường ray) sẽ là String # squish – engineerDave

3

Câu trả lời được lựa chọn sẽ không loại bỏ non-breaking space ký tự.

này nên làm việc trong 1.9:

fixed_string = s.gsub(/(\s|\u00A0)+/, ' ')

+0

Tôi giả định OP muốn xóa khoảng trắng vô nghĩa (tức là chạy nhiều hơn một ký tự trắng) để dọn dẹp và giảm kích thước của chuỗi dành cho HTML, vì nhiều ký tự khoảng trống liên tiếp bị thu gọn thành một không gian bởi trình duyệt web dù sao ... Vì vậy, đáng chú ý là không gian không phá vỡ là _not_ vô nghĩa trong HTML, chúng không bị sụp đổ, tức là bạn có thể không muốn xóa chúng – callum

4

Vấn đề với giải pháp đơn giản nhất gsub(/\s+/, ' ') là nó là rất chậm, vì nó thay thế tất cả các không gian, ngay cả khi nó là duy nhất. Nhưng thường có 1 khoảng cách giữa các từ và chúng ta chỉ nên sửa khi có 2 hoặc nhiều khoảng trắng trong chuỗi.

Better giải pháp là gsub(/[\r\n\t]/, ' ').gsub(/ {2,}/, ' ') - đầu tiên thoát khỏi khoảng trắng đặc biệt và sau đó bóp không gian bình thường

def method1(s) s.gsub!(/\s+/, ' '); s end 
def method2(s) s.gsub!(/[\r\n\t]/, ' '); s.gsub!(/ {2,}/, ' '); s end 

Benchmark.bm do |x| 
    n = 100_000 
    x.report('method1') { n.times { method1("Lorem ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } } 
    x.report('method2') { n.times { method2("Lorem ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } } 
end;1 

#  user  system  total  real 
# method1 4.090000 0.010000 4.100000 ( 4.124844) 
# method2 1.590000 0.010000 1.600000 ( 1.611443) 
11

Trong Rails bạn có thể sử dụng String#squish, mà là một active_support phần mở rộng.

require 'active_support' 

s = <<-EOS 
1/2 cup 

      onion 
EOS 

s.squish 
# => 1/2 cup onion 
Các vấn đề liên quan