O que é um bom perl regex para não ter um caminho absoluto?
-
21-09-2019 - |
Pergunta
Bem, eu tentei e falhei, então, aqui estou eu novamente.
Eu preciso corresponder ao meu padrão de caminho do ABS.
/public_html/mystuff/10000001/001/10/01.cnt
Estou em modo de mancha etc ..
#!/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)});
Preciso abrir o mesmo arquivo algumas vezes ou mais e manchar me força a desprezar o nome do arquivo todas as vezes. Embora eu possa estar fazendo outra coisa errada, ainda preciso de ajuda para construir esse padrão para referência futura.
my $file = "$var[5]";
if ($file =~ /(\w{1}[\w-\/]*)/) {
$under = "/$1\.cnt";
} else {
ErroR();
}
Você pode ver pela minha tentativa iniciante que estou perto de sem noção.
Eu tive que adicionar a barra e extensão para a frente a $1
Devido à minha regex mal construída, mas trabalhando.
Então, eu preciso de ajuda para aprender a consertar minha expressão, então $1
representa /public_html/mystuff/10000001/001/10/01.cnt
Alguém poderia segurar minha mão aqui e me mostrar como fazer:
$file =~ /(\w{1}[\w-\/]*)/
Combine meu caminho absoluto /public_html/mystuff/10000001/001/10/01.cnt
?
Obrigado por qualquer assistência.
Solução
Editar: Usando $
no padrão (como eu fiz antes) não é aconselhável aqui porque pode corresponder \n
No final do nome do arquivo. Usar \z
Em vez disso, porque corresponde inequivocamente ao final da string.
Seja o mais específico possível no que você está correspondendo:
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";
}
Como alternativa, você pode reduzir o espaço vertical ocupado pelo código colocando o que presumo ser um prefixo comum '/public_html/mystuff'
em uma variável e combinando vários componentes em um qr//
construto (veja Perloc Perlop) e depois use o operador condicional ?:
:
#!/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";
Além disso, não posso me reconciliar usando um caminho relativo como você em
$ENV{PATH} = "bin:/usr/bin";
Com o uso do modo de mancha. Você quis dizer
$ENV{PATH} = "/bin:/usr/bin";
Outras dicas
Você fala sobre a imitação do caminho do arquivo toda vez. Provavelmente porque você não está compartimentando as etapas do seu programa.
Em geral, divido esse tipo de programas em etapas. Um dos estágios anteriores é a validação de dados. Antes de deixar o programa continuar, valida todos os dados que puder. Se alguma disso não se encaixa no que eu espero, não deixo o programa continuar. Não quero passar pela metade de algo importante (como inserir coisas em um banco de dados) apenas para descobrir que algo está errado.
Portanto, quando você obtém os dados, sem tudo isso e armazena os valores em uma nova estrutura de dados. Não use os dados originais ou as funções CGI depois disso. O módulo CGI está lá apenas para entregar dados no seu programa. Depois disso, o restante do programa deve saber o mínimo possível sobre o CGI.
Não sei o que você está fazendo, mas quase sempre é um cheiro de design tomar nomes de arquivos reais como entrada.