Вы получаете «0100», потому что у вас есть два оператора print()
.
print $sum;
...
print $courseNum;
И поскольку между ними нет символов новой строки или другого вывода, вы получаете два значения, распечатанные рядом с каждымДругие. $sum
это «0», а $courseNum
это «100».
Так почему же $sum
ноль? Ну, это потому, что ваше регулярное выражение не собирает данные, которые вы хотите, чтобы соответствовать. Ваше регулярное выражение выглядит следующим образом:
m/$courseNum(.+?)align="center">(\d)</
Вы ищете $courseNum
, за которым следует ряд других символов, затем 'align = "center">' и затем ваша цифра. Это не работает по ряду причин.
- Строка "100" появляется много раз в вашем тексте. Много раз это даже не означает номер курса (например, «100%»). Возможно, вам следует искать что-то более точное (
ICS $coursenum
). .+?
не делает то, что вы думаете, что он делает. Точка не соответствует символам новой строки, если вы не используете опцию /s
в операторе сопоставления. - Но даже если вы исправите эти первые две проблемы, она все равно не будет работать, так как есть ряд числовыхячейки таблицы для каждого курса, и вы ничего не делаете для того, чтобы захватить последний. Ваш текущий код получит столбец «Curr. Enrolled», а не «Seats Available».
Это нетривиальная проблема парсинга HTML. Он не должен решаться с помощью регулярных выражений (HTML никогда не должен анализироваться с помощью регулярных выражений). Вы должны взглянуть на один из модулей синтаксического анализа HTML из CPAN - думаю, я бы использовал Web :: Query .
Обновление: Пример решения с использованием Web:: Запрос:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use File::Basename;
use Web::Query;
my $course_num = shift
or die 'Usage: perl ' . basename $0 . " course_number\n";
my $source = 'fa19_ics_class_availability.html';
open my $fh, '<', $source
or die "Cannot open '$source': $!\n";
my $html = do { local $/; <$fh> };
my $count_free;
wq($html)
# Get each table row in the table
->find('table.listOfClasses tr')
->each(sub {
my ($i, $elem) = @_;
my @tds;
# Get each <td> in the <tr>
$elem->find('td')->each(sub { push @tds, $_[1] });
# Ignore rows that don't have 13 columns
return if @tds != 13;
# Ignore rows that aren't about the right course
return if $tds[2]->text ne "ICS $course_num";
# Add the number of available places
$count_free += $tds[8]->text;
});
say $count_free;