Удаление расширения файла из переменной массива

#arrays #perl #variables

#массивы #perl #переменные

Вопрос:

Я пытаюсь удалить расширение файла .png, которое появляется во многих (но не во всех) переменных моего выводимого массива. Переменные массива, которые показывают расширение, делают это потому, что они не были сгенерированы из имен файлов в формате «Genus_species #.png», где «#» — это число. Скорее, они были сгенерированы из ненумерованного имени файла в формате «Genus_species.png». Я полагаю, что эта строка кода создает эту проблему: «$genus = $file =~ s / d.png $// r;». Как мне решить эту проблему? Пожалуйста, сообщите.

Вот мой сценарий на Perl:

 #!/usr/bin/perl
use strict;
use warnings;
use English;   ## use names rather than symbols for special varables

my $dir = '/Users/jdm/Desktop/xampp/htdocs/cnc/images/plants';

opendir my $dfh, $dir  or die "Can't open $dir: $OS_ERROR";
my %genus_species;  ## store matching entries in a hash

for my $file (readdir $dfh)
{
    next unless $file =~ /.png$/; ## entry must have .png extension
    my $genus = $file =~ s/d.png$//r;
    push(@{$genus_species{$genus}}, $file); ## push to array,the @{} is to cast the single entry to a referance to an list
}

for my $genus (keys %genus_species)
{
    print "$genus = ";
    print "$_, " for sort @{$genus_species{$genus}}; # sort and loop     though entries in list referance
    print "n";
}
  

Вот выводимый массив:

 Euonymus_fortunei = Euonymus_fortunei1.png, Euonymus_fortunei2.png, Euonymus_fortunei3.png, 
Polygonum_persicaria = Polygonum_persicaria1.png, Polygonum_persicaria2.png, 
Polygonum_cuspidatum.png = Polygonum_cuspidatum.png,
  

Обратите внимание, что переменная «Polygonum_cuspidatum.png» невольно включает расширение файла, поскольку эта переменная была сгенерирована из файла, в имени которого отсутствовал номер. В частности, эта переменная должна читать:

 Polygonum_cuspidatum = Polygonum_cuspidatum.png
  

Еще раз, пожалуйста, посоветуйте, как решить эту проблему. Спасибо.

Ответ №1:

Вы столкнетесь с той же проблемой, если у вас когда-либо будет многозначное число в имени файла. Это все из-за выбора регулярного выражения:

  s/d.png$//r
  

Это ищет ровно одну цифру, за которой следует .png . Если вам не нужна цифра или любое количество цифр, .png измените свое регулярное выражение как таковое:

 s/d*.png$//r
  

Это говорит о том, что «ноль или более цифр, за которыми следует .png в конце строки».

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

1. Я получаю ошибки, используя «s / d * .png $ // r». Я исследую, почему.

2. После добавления ; в конце выражения это работает… но он возвращает только 513 записей, а не ожидаемые 585. Я исследую, почему.

3. Если бы у вас когда-либо раньше genus_species11.png это было, это привело бы к созданию элемента массива genus_species1[] с вашим предыдущим регулярным выражением.

4. Нет имен файлов, превышающих число 9. Действительно странно, что увеличение области поиска приведет к возврату меньшего количества файлов!

5. Re «, в котором говорится «ноль или более цифр, за которыми следует .png в конце строки». «, Нет, это не так. Это было бы d*.pngz . У вас есть «ноль или более цифр, за которыми следует .png и, возможно, LF в конце строки».