Як видалити повернення каретки за допомогою Ruby?


75

Я думав, що цей код спрацює, але регулярний вираз ніколи не відповідає \ r \ n. Я переглянув дані, які читаю в шістнадцятковому редакторі, і переконався, що у файлі справді є шістнадцятковий шаблон D та шістнадцятковий шаблон.

Я також пробував регулярні вирази / \ xD \ xA / m та / \ x0D \ x0A / m, але вони також не збігалися.

Зараз це мій код:

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

На додаток до альтернатив, було б непогано знати, що я роблю не так (щоб полегшити навчання з мого боку). :)

Відповіді:


23

Що ви отримуєте, коли робите puts lines? Це дасть вам підказку.

За замовчуванням File.openвідкриває файл у текстовому режимі, тому ваші \r\nсимволи будуть автоматично перетворені в \n. Можливо, в цьому причина linesзавжди рівна lines2. Щоб Ruby не розбирав кінці рядка, використовуйте rbрежим:

C: \> скопіювати con lala.txt
a
файл
з
багато
ліній
^ Z

C: \> irb
irb (main): 001: 0> text = File.open ('lala.txt'). read
=> "a \ nфайл \ nз \ nбагато \ n рядками \ n"
irb (основна): 002: 0> bin = File.open ('lala.txt', 'rb'). прочитати
=> "a \ r \ nфайл \ r \ nз \ r \ nбагато \ r \ nлініями \ r \ n"
irb (основний): 003: 0>

Але з вашого запитання та коду я бачу, що вам просто потрібно відкрити файл із модифікатором за замовчуванням. Вам не потрібно перетворення, і ви можете використовувати коротший File.read.


2
Там в відповідь з великою кількістю upvotes , спрямованим на «Газа» Newlines подальшого вниз: stackoverflow.com/a/7095275/403234
yas4891

169

Використовуйте смужку String #

Повертає копію str із видаленими пробілами на початку та в кінці.

напр

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

Використання gsub

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

5
Він не буде фільтрувати нові рядки в середині тексту: "line1 \ n line2" .strip # => "line1 \ n line2"
ndrix

Якщо використовується під час each_lineдзвінка, то це не має значення.
Ян Воган,

9
Видалення всього навколишнього пробілу! = Видалення повернення каретки
Barry Kelly

36

Як правило, коли я маю справу з зачищенням \ r або \ n, я шукатиму обидва, роблячи щось на зразок

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

Я виявив, що залежно від того, як були збережені дані (використовувана ОС, використовуваний редактор, відношення Юпітера до Іо на той момент), після повернення каретки може бути новий рядок, а може і не бути. Це здається дивним, що ви бачите обох символів у шістнадцятковому режимі. Сподіваюся, це допомагає.


22

Якщо ви використовуєте Rails, існує squishметод

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

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


це чудова порада!
bryanus

2
Для користувачів, які не є Rails, це реалізовано якstr.gsub(/[[:space:]]+/, ' ').strip
sobstel

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

Дуже дякую! Це рятує мій день!
Rubyrider

2
Це замінює будь-який пробіл, а не лише CR /
LF



6

Як щодо наступного?

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>

Або ...

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>

також я перевірив: "\ r \ n"! = "\ n". Отже, схоже, оригінальний код плакатів правильний.
чемпіон

4

Я думаю, що ваш регулярний вираз майже завершений - ось що я б зробив:

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

У наведеному вище я помістив \ r та \ n у клас (таким чином, не має значення, в якому порядку вони можуть з'являтися) і додав кваліфікатор "+" (так, щоб "\ r \ n \ r \ n \ r \ n "також збігається один раз, і все це замінюється на" \ n ")






0
def dos2unix(input)
  input.each_byte.map { |c| c.chr unless c == 13 }.join
end

remove_all_the_carriage_returns = dos2unix(some_blob)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.