#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
). Лексические дескрипторы файлов имеют много преимуществ по сравнению с простыми дескрипторами файлов:
- Они лексически ограничены, а не глобальны
- Они закрываются, когда выходят из области видимости, а не в конце программы
- Их легче передавать в функции (т. Е. Вам не нужно использовать ссылку на typeglob).
Вы используете их так же, как если бы вы использовали дескриптор файла bareword.
Другие вещи, которые вы, возможно, захотите рассмотреть:
- используйте строгую прагму
- используйте прагму предупреждений
- работайте с файлами по строке или фрагменту за раз, а не считывайте их все сразу
- используйте синтаксический анализатор HTML вместо регулярных выражений
- используйте именованные переменные вместо переменной по умолчанию (
$_
) - если вы используете переменную по умолчанию, не включайте ее там, где она уже будет использоваться (например
s/foo/bar/;
, вместо$_ =~ s/foo/bar/;
)
Номер 4 может быть очень важен для того, что вы делаете. Если вы не уверены в формате, в котором находятся эти HTML-файлы, вы можете легко что-то пропустить. Например, "Authors Here"
и "AuthorsnHere"
означает то же самое для HTML, но ваше регулярное выражение пропустит позже. Возможно, вы захотите взглянуть на XML::Twig
(я знаю, что там написано XML, но он также обрабатывает HTML). Это очень простой в использовании анализатор XML / HTML.