Есть ли способ обозначить разделитель лексемы в программе чтения файлов Perl? - PullRequest
1 голос
/ 06 апреля 2010

Я читаю текстовый файл через CGI в perl и замечаю, что при сохранении файла в mac textEdit разделитель строк распознается, но когда я загружаю CSV, который экспортируется прямо из Excel, они не , Я предполагаю, что это проблема \ n против \ r, но это заставило меня задуматься о том, что я не знаю, как указать, каким должен быть токен-терминатор строки, если я не хочу тот, который ищет по умолчанию.

Ответы [ 4 ]

4 голосов
/ 06 апреля 2010

Да. Вы хотите перезаписать значение $/. От perlvar

$ /

Разделитель входных записей, новая строка по умолчанию. Это влияет на представление Perl о том, что такое «линия». Работает как переменная RS в awk, включая обработку пустых строк как терминатора, если для него задана нулевая строка. (Пустая строка не может содержать пробелов или табуляции.) Вы можете установить ее в многосимвольную строку, чтобы соответствовать многосимвольному терминатору, или в undef, чтобы прочитать конец файла. Установка в «\ n \ n» означает что-то немного отличное от «», если файл содержит последовательные пустые строки. Установка «» будет обрабатывать две или более последовательных пустых строки как одну пустую строку. Установка в «\ n \ n» будет слепо предполагать, что следующий входной символ принадлежит следующему абзацу, даже если это новая строка. (Мнемоника: / ограничивает границы строк при цитировании стихов.)

local $/;           # enable "slurp" mode
local $_ = <FH>;    # whole file now here
s/\n[ \t]+/ /g;

Помните: значение $ / является строкой, а не регулярным выражением. awk должен быть лучше для чего-то. : -)

Установка $ / в качестве ссылки на целое число, скаляр, содержащий целое число, или скаляр, который может быть преобразован в целое число, будет пытаться читать записи вместо строк, при этом максимальный размер записи является ссылочным целым числом. Итак, это:

local $/ = \32768; # or \"32768", or \$var_containing_32768
open my $fh, "<", $myfile or die $!;
local $_ = <$fh>;

будет читать запись не более 32768 байт из FILE. Если вы не читаете из файла, ориентированного на запись (или ваша ОС не имеет файлов, ориентированных на запись), то, скорее всего, вы получите полный кусок данных при каждом чтении. Если запись превышает установленный вами размер записи, вы получите запись обратно по частям. Попытка установить размер записи равным нулю или менее приведет к чтению (всего) файла целиком.

В VMS чтение записей выполняется с помощью эквивалента sysread, поэтому лучше не смешивать чтение записей и записей без одного и того же файла. (Это вряд ли будет проблемой, потому что любой файл, который вы хотите прочитать в режиме записи, вероятно, непригоден для использования в линейном режиме.) Системы, не относящиеся к VMS, выполняют нормальный ввод-вывод, поэтому безопасно смешивать записи и чтения без записи файла.

См. Также "Новые строки" в perlport. Также см. $ ..

2 голосов
/ 06 апреля 2010

Переменная имеет несколько имен:

  • $/
  • $RS
  • $INPUT_RECORD_SEPARATOR

Для более длинных имен вам нужно:

use English;

Не забудьте тщательно локализовать:

{
local($/) = "\r\n";
...code to read...
}
1 голос
/ 06 апреля 2010

Если вы читаете в файле с разделителями строк CRLF, вы можете открыть его с помощью дисциплины CRLF или установить бинмод дескриптора для автоматического перевода.

open my $fh, '<:crlf', 'the_csv_file.csv' or die "Oh noes $!";

Это будет прозрачно преобразовано \r\n последовательностей в \n последовательностей.

Вы также можете применить этот перевод к существующему дескриптору, выполнив:

binmode( $fh, ':crlf' );

:crlf Режим обычно по умолчанию в средах Win32 Perl и работаеточень хорошо на практике.

0 голосов
/ 21 июня 2019

Для чтения файла CSV следуйте советам Роберта-П в его комментарии и используйте модуль CSV.

Но для общего случая чтения строк из файла с разными окончаниями строк я обычно делаю весь файл целым и разбивает его на \R. Если это не мультигигабайтный файл, это должен быть самый безопасный и простой способ.

Итак:

perl -0777 -nle 'my @lines = split /\R/;
    print length($_), " bytes split into ", scalar(@lines), " lines."' $YOUR_FILE

или в вашем скрипте:

{
  local $/ = undef;
  open F, $YOUR_FILE or die;
  @lines = split /\R/, <F>;
  close F;
}

\R работает с Unix LF (\x0A), Windows / Internet CRLF, а также с CR (\x0D), который использовался Mac в девяностых, но фактически все еще используется некоторыми программами Mac.

Из perldoc :

\ R соответствует общей новой строке; то есть что-либо считается разрывом строки последовательность по Юникоду. Это включает в себя все символы, соответствующие \ v (вертикальный пробел) и многосимвольная последовательность "\ x0D \ x0A" (возврат каретки с последующим переводом строки, иногда называемый сетью новая линия; это конец строки, используемый в текстовых файлах Microsoft открыт в двоичном режиме)

Или посмотрите это более приятное и исчерпывающее объяснение \R в статье Брайана Д. Фоя: Конечная строка \ R, оканчивающаяся , в которой даже есть пара забавных видео.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...