Как получить доступ к массиву в Perl для Regex - PullRequest
4 голосов
/ 29 января 2011

У меня есть два ввода, которые читаются в моей командной строке, первый из которых представляет собой последовательность слов, которые должны быть найдены программой, которую я пишу, а второй - это файл, содержащий слова, в которых нужно найти слова.Так, например, моя командная строка читает perl WebScan.pl word WebPage000.htm

Теперь у меня нет проблем с доступом к любому из этих входов для печати, но у меня возникают большие трудности с доступом к содержимому веб-страницы, поэтомуЯ могу выполнять регулярные выражения для удаления тегов HTML и доступа к содержимому.Я понимаю, что для этого есть подпрограмма без регулярных выражений, которая гораздо более эффективна, но мне нужно работать с регулярными выражениями :(.

Я могу без проблем получить доступ к html-файлу для печати:

open (DATA, $ARGV[1]);
my @file = <DATA>;
print @file;

, которая печатает весь код html-страницы, но я не могу передать регулярные выражения для удаления html-блоков. Я получаю сообщение об ошибке «Не удается изменить разыменование массива в s/// рядом, "где у меня есть мое конкретное регулярное выражение. Я не уверен, как обойти это - я попытался преобразовать массив в скаляр, но тогда я не могу получить доступ к любым данным вhtml вообще (и нет, он не просто печатает количество значений в массиве: P)

Как мне получить доступ к содержимому массива, чтобы я мог использовать регулярные выражения для уточнения желаемого результата?

1 Ответ

15 голосов
/ 29 января 2011

Похоже, вы делаете что-то вроде @file =~ s/find/replace/;.Вы получаете эту ошибку, потому что левая часть оператора привязки регулярного выражения налагает скалярный контекст на его аргумент.Массив в скалярном контексте возвращает свою длину, но это значение доступно только для чтения.Поэтому, когда ваша подстановка пытается выполнить замену, kaboom.

Чтобы обработать все строки файла, вы можете использовать цикл foreach:

foreach my $line (@file) {$line =~ s/find/replace/}

или болеевкратце, как:

s/find/replace/ for @file;

Однако, если вы запускаете регулярные выражения в файле HTML, скорее всего, вам понадобится, чтобы они совпали по нескольким строкам.То, что вы делаете выше, - это чтение всего файла и сохранение каждой строки как элемента @file.Если вы используете одну из итеративных структур управления Perl в массиве, вы не сможете сопоставить несколько строк.Поэтому вместо этого вы должны прочитать файл в единый скаляр.Затем вы можете использовать $file =~ s///, как и ожидалось.

Файл можно сжать в одну переменную, временно очистив разделитель входной записи $/:

my $file = do {local $/; <DATA>};

В общем случае регулярные выраженияэто неправильный инструмент для разбора HTML, но звучит так, будто это домашнее задание, поэтому в любом случае его просто попрактикуйте.

И, наконец, в современном Perl вы должны использовать форму с тремя аргументами open с лексическим дескриптором файла и проверкой ошибок:

open my $DATA, '<', $ARGV[1] or die "open error: $!";

my $file = do {local $/; <$DATA>};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...