PERL: БИБЛИОТЕКА ПРОГРАММИСТА - стр. 47
1.5. Посимвольная обработка строк 37
Решения с функциями split и unpack предоставляют массив символов, с которым можно работать. Если массив не нужен, воспользуйтесь поиском по шаблону в цикле while с флагом /д, который будет извлекать по одному символу:
%seen =();
$string = "an apple a day";
while ($string =~ /(.)/g) {
$seen($1)++; }
print "unique chars are: ", sort(keys %seen), "\n"; unique chars are: adelnpy
Как правило, посимвольная обработка строк не является оптимальным решением. Вместо использования index/substr или split/unpack проще воспользоваться шаблоном. В следующем примере 32-разрядная контрольная сумма вычисляется вручную, но лучше поручить работу функции unpack — она сделает то же самое намного эффективнее.
Следующий пример вычисляет контрольную сумму символов $st ring в цикле f о reach. Приведенный алгоритм не оптимален; просто мы используем традиционную и относительно легко вычисляемую сумму. За более достойной реализацией контрольной суммы обращайтесь к модулю MD5 на CPAN.
$sum = 0;
foreach $ascval (unpack("O", $string)) {
$sum += $ascval; > print "sum is $sum\n";
# Для строки "an apple a day" выводится сумма 1248
Следующий вариант делает то же самое, но намного быстрее:
$sum = unpack("%32C", $string);
Это позволяет эмулировать программу вычисления контрольной суммы SysV:
#!/usr/bin/perl
# sum - Вычисление 16-разрядной контрольной суммы всех входных файлов
«checksum = 0;
while (о) { $checksum += unpack("%16O", $_) } Schecksum %= (2 •• 16) - 1; print "$checksum\n";
На практике пример использования выглядит так:
% perl sum /etc/termcap 1510
Если у вас установлена GNU-версия sum, для получения идентичного ответа для того же файла ее следует вызвать с параметром -sysv:
% sum -sysv /etc/termcap 1510 851 /etc/termcap
В примере 1.1 приведена еще одна крошечная программа, в которой также реализована посимвольная обработка входных данных. Идея заключается в том, что-
