Универсална поддръжка за нов ред в Ruby, която включва \r (CR) окончания на редове

В приложение на Rails приемам и анализирам CSV файлове, които може да са форматирани с всеки от трите възможни знака за завършване на ред: \n (LF), \r\n (CR+LF) или \r (CR). Изглежда, че библиотеките File и CSV на Ruby се справят добре с първите два случая, но последният случай ("Mac classic" \r окончания на редове) не се обработва като нов ред. Важно е да можете да приемете този формат, както и другите, тъй като изглежда, че Microsoft Excel за Mac (работещ на OS X) го използва, когато експортира към „Стойности, разделени със запетая“ (въпреки че експортирането към „Windows Comma Separated“ прави по-лесно -за обработка \r\n).

Python има "универсална поддръжка за нов ред" и ще се справи с всеки от тези три формата без проблем. Има ли нещо подобно в Ruby, което ще приеме и трите, без да знае формата предварително?


person jrdioko    schedule 23.09.2013    source източник
comment
Не, Руби не прави това. Той усеща операционната система и въз основа на това приема правилните краища на редовете. Старият Macintosh \r не се вижда в текущия изход, откакто Mac премина към Mac OS X, който използва *nix \n. Покажете ни как отваряте вашите CSV файлове и вероятно ще можем да ви покажем някои трикове, за да се справите с всички споменати краища на редове с малка корекция.   -  person the Tin Man    schedule 24.09.2013
comment
@theTinMan: Проблемът е, че можете да получите CSV файл от старата школа на MacOS с \r EOL, когато работите на Linux, който очаква \n EOL. Така че файлът и операционната система няма непременно да се споразумеят за това какъв трябва да бъде разделителят на CSV записи.   -  person mu is too short    schedule 24.09.2013


Отговори (1)


Можете да използвате :row_sep => :auto:

:row_sep
Низът, добавен в края на всеки ред. Това може да бъде зададено на специалната настройка :auto, която изисква CSV автоматично да открие това от данните. Автоматичното откриване чете напред в данните, търсейки следващата последователност "\r\n", "\n" или "\r".

Разбира се, има някои предупреждения, вижте ръководството, свързано по-горе, за подробности.

Можете също така да почистите ръчно EOL с малко gsubing, преди да предадете данните на CSV за анализ. Вероятно бих поел по този път и ръчно бих конвертирал всички \r\ns и \rs в единични \ns, преди да се опитам да анализирам CSV. OTOH, това няма да работи толкова добре, ако във вашия CSV има вградени двоични данни, където \rs означават нещо. От гледна точка на хващането, това е CSV, с който имаме работа, така че кой знае с какви луди счупени глупости ще се сблъскате.

person mu is too short    schedule 23.09.2013
comment
+1 много хубав улов! Надявам се, че се чете напред за всеки ред, защото в миналото съм срещал CSV файлове, които съдържат смесица от завършвания на редове, поради това, че някой е добавил Windows CSV към Mac CSV. Това беше PITA. - person the Tin Man; 24.09.2013
comment
@theTinMan: Мисля, че :auto търси първия от трите EOL и го прилага към цялото нещо. В реалния живот вероятно бих обработил предварително данните, за да стандартизирам EOL до \n, преди да направя каквото и да било, CSV е толкова ужасно злоупотребяван формат, че никога не знаеш с какви прецакани глупости ще си имаш работа. - person mu is too short; 24.09.2013
comment
Страхотен отговор, благодаря! И gsub ще бъде нещо като input.gsub(/\r\n?/, "\n")? - person jrdioko; 24.09.2013