Чтение строк с символами продолжения

Проблема

Имеется файл с длинными строками, которые делятся на две и более строки. Символ \ означает, что данная строка продолжается на следующей. Вы хотите объединить разделенные строки. Подобное разделение длинных строк на короткие встречается в make-файлах, сценариях командного интерпретатора, конфигурационных файлах и многих языках сценариев.

Решение

Последовательно объединяйте прочитанные строки, пока не встретится строка без символа продолжения:
while (defined($line = <FH>) ) {
  chomp $line;
  if ($line =~ s/\\$//) {
    $line .= <FH>;
    redo unless eof(FH);
  }
  # Обработать полную запись в $line
}

Комментарий

Рассмотрим пример входного файла:
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) \
            $(TEXINFOS) $(INFOS) $(MANS) $(DATA)
DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) \
                $(TEXINFOS) $(INFO_DEPS) $(MANS) $(DATA) \
                $(EXTRA,DIST)
Вы хотите обработать текст, игнорируя внутренние разрывы строк. В приведенном примере первая запись занимает две строки, вторая — три строки и т. д.
Алгоритм работает следующим образом. Цикл while читает строки, которые могут быть, а могут и не быть полными записями, — они могут заканчиваться символом \ (и переводом строки). Оператор подстановки s/// пытается удалить \ в конце строки. Если подстановка заканчивается неудачей, значит, мы нашли строку без \. В противном случае мы читаем следующую запись, приписываем ее к накапливаемой переменной $line и возвращаемся к началу цикла while с помощью redo. Затем выполняется команда chomp.
У файлов такого формата имеется одна распространенная проблема — невидимые пробелы между \ и концом строки. Менее строгий вариант подстановки выглядит так:
if ($line =~ s/\\\s*$//) {
  # Как и прежде
}
К сожалению, даже если ваша программа прощает мелкие погрешности, существуют и другие, которые этого не делают. Будьте снисходительны к входным данным и строги — к выходным.

См. также

Описание функции chomp; описание ключевого слова redo



2013-09-10 17:05:19

Proverte kod v komentariyah gde pro list tam oshibki detskie




Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: