Скрипт Perl для поиска и замены не работает?

#perl #replace

#perl #заменить

Вопрос:

Я пытаюсь создать скрипт на Perl для замены текста во всех HTML-файлах в данном каталоге. Однако он не работает. Кто-нибудь может объяснить, что я делаю не так?

 my @files = glob "ACM_CCS/*.html";

foreach my $file (@files)
{
    open(FILE, $file) || die "File not found";
    my @lines = <FILE>;
    close(FILE);

    my @newlines;
    foreach(@lines) {
        $_ =~ s/Authors Here/Authors introduced this subject for the first time in this paper./g;
        #$_ =~ s/Authors Elsewhere/Authors introduced this subject in a previous paper./g;
        #$_ =~ s/D4-/D4: Is the supporting evidence described or cited?/g;
        push(@newlines,$_);
    }

    open(FILE, $file) || die "File not found";
    print FILE @newlines;
    close(FILE);
}
  

Например, я бы хотел заменить «D4-» на «D4: это …»и т.д. Спасибо, я был бы признателен за любые советы.

Комментарии:

1. Всегда use strict; и use warnings 'all'; ! Включение предупреждений дало бы вам хороший намек на то, что не так.

2. Спасибо. Позвольте мне посмотреть, какие отзывы я получу.

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

Ответ №1:

Вы используете версию с двумя аргументами open . Если $file не начинается с «<«, «>» или «>>», он будет открыт как дескриптор файла для чтения. Вы не можете выполнить запись в дескриптор прочитанного файла. Чтобы решить эту проблему, используйте версию open с тремя аргументами:

 open my $in, "<", $file or die "could not open $file: $!";
open my $out, ">", $file or die "could not open $file: $!";
  

Также обратите внимание на использование лексических дескрипторов файлов ( $in ) вместо дескрипторов файлов bareword ( FILE ). Лексические дескрипторы файлов имеют много преимуществ по сравнению с простыми дескрипторами файлов:

  1. Они лексически ограничены, а не глобальны
  2. Они закрываются, когда выходят из области видимости, а не в конце программы
  3. Их легче передавать в функции (т. Е. Вам не нужно использовать ссылку на typeglob).

Вы используете их так же, как если бы вы использовали дескриптор файла bareword.

Другие вещи, которые вы, возможно, захотите рассмотреть:

  1. используйте строгую прагму
  2. используйте прагму предупреждений
  3. работайте с файлами по строке или фрагменту за раз, а не считывайте их все сразу
  4. используйте синтаксический анализатор HTML вместо регулярных выражений
  5. используйте именованные переменные вместо переменной по умолчанию ( $_ )
  6. если вы используете переменную по умолчанию, не включайте ее там, где она уже будет использоваться (например s/foo/bar/; , вместо $_ =~ s/foo/bar/; )

Номер 4 может быть очень важен для того, что вы делаете. Если вы не уверены в формате, в котором находятся эти HTML-файлы, вы можете легко что-то пропустить. Например, "Authors Here" и "AuthorsnHere" означает то же самое для HTML, но ваше регулярное выражение пропустит позже. Возможно, вы захотите взглянуть на XML::Twig (я знаю, что там написано XML, но он также обрабатывает HTML). Это очень простой в использовании анализатор XML / HTML.