2008-11-13 30 views
65

Tôi nghĩ mã này sẽ hoạt động, nhưng cụm từ thông dụng không bao giờ khớp với \ r \ n. Tôi đã xem dữ liệu tôi đang đọc trong một trình soạn thảo hex và xác minh có thực sự là một hex D và hex Một mẫu trong tập tin.Làm thế nào để loại bỏ trở về vận chuyển bằng Ruby?

Tôi cũng đã thử các biểu thức chính quy/\ xD \ xA/m và/\ x0D \ x0A/m nhưng chúng cũng không khớp.

Đây là mã của tôi ngay bây giờ:

lines2 = lines.gsub(/\r\n/m, "\n") 
    if (lines == lines2) 
     print "still the same\n" 
    else 
     print "made the change\n" 
    end 

Ngoài lựa chọn thay thế, nó sẽ được tốt đẹp để biết những gì tôi đang làm sai (để tạo điều kiện một số học tập trên một phần của tôi). :)

Trả lời

23

Bạn nhận được gì khi thực hiện puts lines? Điều đó sẽ cho bạn một đầu mối.

Theo mặc định File.open mở tệp ở chế độ văn bản, vì vậy, \r\n ký tự của bạn sẽ tự động được chuyển đổi thành \n. Có lẽ đó là lý do lines luôn bằng lines2. Để ngăn chặn Ruby từ phân tích các dòng kết thúc sử dụng rb chế độ:

C:\> copy con lala.txt 
a 
file 
with 
many 
lines 
^Z 

C:\> irb 
irb(main):001:0> text = File.open('lala.txt').read 
=> "a\nfile\nwith\nmany\nlines\n" 
irb(main):002:0> bin = File.open('lala.txt', 'rb').read 
=> "a\r\nfile\r\nwith\r\nmany\r\nlines\r\n" 
irb(main):003:0> 

Nhưng từ câu hỏi và mã của bạn tôi thấy bạn chỉ cần mở file với modifier mặc định. Bạn không cần bất kỳ chuyển đổi nào và có thể sử dụng File.read ngắn hơn.

+2

Có câu trả lời với số lượng upvotes khác hướng đến "Đường kẻ sọc" tiếp tục xuống: http://stackoverflow.com/a/7095275/403234 – yas4891

15
lines2 = lines.split.join("\n") 
+4

này cũng sẽ tước tab và khoảng trắng, trong đó có thể không phải những gì người dùng muốn. – Doug

6

Làm cách nào sau đây?

irb(main):003:0> my_string = "Some text with a carriage return \r" 
=> "Some text with a carriage return \r" 
irb(main):004:0> my_string.gsub(/\r/,"") 
=> "Some text with a carriage return " 
irb(main):005:0> 

Hoặc ...

irb(main):007:0> my_string = "Some text with a carriage return \r\n" 
=> "Some text with a carriage return \r\n" 
irb(main):008:0> my_string.gsub(/\r\n/,"\n") 
=> "Some text with a carriage return \n" 
irb(main):009:0> 
+0

cũng vậy, tôi đã kiểm tra: "\ r \ n"! = "\ N". Vì vậy, có vẻ như mã áp phích ban đầu là đúng. – rampion

33

Nói chung khi tôi đối phó với tước \ n \ r hay, tôi sẽ xem xét cho cả hai bằng cách làm một cái gì đó giống như

lines.gsub(/\r\n?/, "\n"); 

Tôi đã thấy rằng tùy thuộc vào cách dữ liệu được lưu (hệ điều hành được sử dụng, trình soạn thảo được sử dụng, mối quan hệ của Sao Mộc đối với Io vào thời điểm đó) có thể có hoặc không thể là dòng mới sau khi trở về vận chuyển. Nó có vẻ lạ mà bạn nhìn thấy cả hai ký tự trong chế độ hex. Hi vọng điêu nay co ich.

149

Sử dụng String#strip

Trả về một bản sao của str với hàng đầu và dấu khoảng trắng loại bỏ.

ví dụ

" hello ".strip #=> "hello" 
"\tgoodbye\r\n".strip #=> "goodbye" 

Sử dụng gsub

string = string.gsub(/\r/," ") 
string = string.gsub(/\n/," ") 
+5

Nó sẽ không lọc dòng mới ở giữa văn bản: "line1 \ n line2 ".strip # =>" line1 \ n line2 " – ndrix

+0

Nếu được sử dụng trong một cuộc gọi' each_line', thì điều đó không quan trọng. –

+5

Xóa tất cả khoảng trống xung quanh! = Xóa bỏ các dấu nháy dòng –

2

Tại sao không đọc các tập tin trong chế độ văn bản, chứ không phải là chế độ nhị phân?

17
modified_string = string.gsub(/\s+/, ' ').strip 
+0

Cảm ơn rất nhiều! Nó tiết kiệm trong ngày của tôi! – Rubyrider

+2

Điều này thay thế bất kỳ ký tự khoảng trắng nào, không chỉ CR/LFs – hoffmanc

1

Bạn có thể sử dụng này:

my_string.strip.gsub(/\s+/, ' ') 
+1

Về cơ bản câu trả lời giống với câu trả lời giống như [this one] (http://stackoverflow.com/a/8891341/1735262) ​​ở trên. – iamnotmaynard

12

Nếu bạn đang sử dụng Rails, có một phương pháp squish

"\tgoodbye\r\n".squish => "goodbye"

"\tgood \t\r\nbye\r\n".squish => "good bye"

+0

đây là một mẹo tuyệt vời! – bryanus

+0

Đối với người dùng không có Rails, nó được triển khai dưới dạng 'str.gsub (/ [[: không gian:]] + /, '') .strip' – sobstel

0

Tôi nghĩ rằng regex của bạn là gần như hoàn toàn - đây là những gì tôi sẽ làm:

lines2 = lines.gsub(/[\r\n]+/m, "\n") 

Ở phía trên, tôi đã đặt \ r \ n vào một lớp (theo cách đó, không quan trọng thứ tự xuất hiện của chúng) và thêm "+" vòng loại (để "\ r \ n \ r \ n \ r \ n" cũng sẽ khớp một lần, và toàn bộ thay thế bằng "\ n")

0

Chỉ cần một biến thể:

lines.delete(" \n") 
Các vấn đề liên quan