Что хорошего в регулярном выражении Perl, чтобы не указывать абсолютный путь? - PullRequest
2 голосов
/ 13 октября 2009

Ну, я попытался и потерпел неудачу, вот и я снова.

Мне нужно соответствовать моей схеме пресса.

 /public_html/mystuff/10000001/001/10/01.cnt

Я нахожусь в грязном режиме и т.д ..

#!/usr/bin/perl -Tw
use CGI::Carp qw(fatalsToBrowser);
use strict;
use warnings;
$ENV{PATH} = "bin:/usr/bin";
delete ($ENV{qw(IFS CDPATH BASH_ENV ENV)});

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

my $file = "$var[5]";
if ($file =~ /(\w{1}[\w-\/]*)/) {
$under = "/$1\.cnt";
} else {
ErroR();
}

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

Мне пришлось добавить косую черту и расширение к $1 из-за моего плохо сконструированного, но работающего регулярного выражения.

Итак, мне нужна помощь, чтобы научиться исправлять свое выражение, поэтому $1 представляет /public_html/mystuff/10000001/001/10/01.cnt

Может ли кто-нибудь держать меня здесь за руку и показать мне, как сделать:

$file =~ /(\w{1}[\w-\/]*)/ соответствует моему абсолютному пути /public_html/mystuff/10000001/001/10/01.cnt?

Спасибо за любую помощь.

Ответы [ 2 ]

7 голосов
/ 13 октября 2009

Редактировать: Использование $ в шаблоне (как я делал раньше) здесь не рекомендуется, поскольку оно может соответствовать \n в конце имени файла. Вместо этого используйте \z, поскольку он однозначно совпадает с концом строки.

Будьте максимально точны в том, что вы подходите:

my $fn = '/public_html/mystuff/10000001/001/10/01.cnt';

if ( $fn =~ m!
    ^(
        /public_html
        /mystuff
        /[0-9]{8}
        /[0-9]{3}
        /[0-9]{2}
        /[0-9]{2}\.cnt
     )\z!x ) {
     print $1, "\n";
 }

В качестве альтернативы вы можете уменьшить вертикальное пространство, занимаемое кодом, поместив в переменную то, что я предполагаю в качестве общего префикса '/public_html/mystuff', и комбинируя различные компоненты в конструкции qr// (см. perldoc perlop ), а затем используйте условный оператор ?::

#!/usr/bin/perl

use strict;
use warnings;

my $fn = '/public_html/mystuff/10000001/001/10/01.cnt';
my $prefix = '/public_html/mystuff';
my $re = qr!^($prefix/[0-9]{8}/[0-9]{3}/[0-9]{2}/[0-9]{2}\.cnt)\z!;

$fn = $fn =~ $re ? $1 : undef;

die "Filename did not match the requirements" unless defined $fn;
print $fn, "\n";

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

$ENV{PATH} = "bin:/usr/bin";

с использованием режима загрязнения. Вы имели в виду

$ENV{PATH} = "/bin:/usr/bin";
6 голосов
/ 14 октября 2009

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

В общем, я разбиваю программы такого рода на этапы. Одним из ранних этапов является проверка данных. Прежде чем я продолжу программу, я проверяю все данные, которые могу. Если что-то из этого не соответствует ожидаемому, я не позволяю программе продолжаться. Я не хочу идти наполовину через что-то важное (например, вставлять вещи в базу данных), только чтобы обнаружить, что что-то не так.

Итак, когда вы получаете данные, снимите их все и сохраните значения в новой структуре данных. Не используйте исходные данные или функции CGI после этого. Модуль CGI как раз для передачи данных в вашу программу. После этого остальная часть программы должна знать как можно меньше о CGI.

Я не знаю, что вы делаете, но почти всегда пахнет дизайном, принимая в качестве входных данных настоящие имена файлов.

...