2009-10-13 5 views
2

글쎄, 나는 노력했으나 실패했다, 나는 다시 여기있다.절대 경로를 얻을 수없는 좋은 Perl 정규식이란 무엇입니까?

내 복근 경로 패턴과 일치해야합니다. 나는 더러운 모드 등에서 오전

/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)}); 

나는 파일 이름마다 시간을 untaint 동일한 파일을 몇 번 이상 더러운 힘 저를 열어야합니다. 내가 다른 뭔가 잘못하고있을 수도 있지만, 나는 미래의 참조를 위해이 패턴을 만드는 데 도움이 필요합니다.

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

나는 초보자 시도에서 내가 우둔한 사람이라는 것을 알 수 있습니다.

제대로 작성되지 않았지만 작동하는 정규식으로 인해 슬래시 및 확장자를 $1에 추가해야했습니다.

$file =~ /(\w{1}[\w-\/]*)/ 내 절대 경로 /public_html/mystuff/10000001/001/10/01.cnt 일치 :

그래서, 내가 어떻게 그렇게 $1/public_html/mystuff/10000001/001/10/01.cnt

누군가가 여기 내 손을 잡아 수 나타내는 내 표현을 수정하고 만드는 방법을 내게 보여 학습의 도움이 필요합니다?

어떤 도움을 주셔서 감사합니다.

+0

그건 그렇고,'$ file = $ var [5];'충분하다; '$ var [5]'를 인용 할 필요가 없습니다. http://perldoc.perl.org/perlfaq4.html#What%27s-wrong-with-always-quoting-%22%24vars%22%3f를 참조하십시오. 또한 '@ var'은 나쁜 것입니다. 이름. –

+0

고맙습니다. 그렇습니다. "var"는 질문에서 가능한 한 명확히하기 위해 수갑을 벗어났습니다. 나는 아직도 이중 따옴표를 배우지 않거나 규칙을 배우지 않고있다. 나는 작은 따옴표 -vs- double을 이해하므로 실제로 배우고 있습니다. –

+1

/(\ w {1} [\ w - \ /] *) /는 슬레시 또는 확장과 일치하지 않습니다. /\/?(\w{1}[\w-\/\.]*)/와 같은 것이 필요할 것입니다. 선택적인 선행 슬래시를 추가했음을 주목하고, 첫 번째 단어 다음에 마침표를 추가했습니다. 물론 아래의 답은 여전히 ​​더 낫습니다. 가능한 한 더 구체적입니다. 그러나 배우기 위해서이 대답을 갖는 것이 중요하다고 생각합니다. :) – Rini

답변

7

편집 :이 파일 이름의 끝에 \n 일치 할 수 있기 때문에 (내가 전에 그랬던 것처럼) 패턴에서 $을 사용 여기에 권장하지 않습니다. 문자열의 끝 부분과 모호하지 않게 일치하므로 \z을 대신 사용하십시오.

당신이 일치하는 가능한 한 구체적으로 : 내가 변수의 일반적인 접두사 '/public_html/mystuff'로 가정 무엇을 넣어

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"; 
} 

을 다른 방법으로,이 코드에 의해 촬영 수직 공간을 줄일 수 있으며, 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"; 

를 I 상대 경로 등을 사용하여 조정할 수없는 당신은 안으로 할

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

오염 모드를 사용하여. 당신은 의미 했습니까

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

감사합니다 @ 사이 난, 나는 $ ENV {PATH}가 정확하지 않다는 것을 알지 못했습니다. 모든 것이 제대로 작동했지만 미래에 문제가되었을 수 있습니다. 감사. 한 번에 그 패턴에 대해서 정말 가까이에있었습니다. 나는 $! x를 끝내지 않았다. 그리고 나는 좌절감을 포기하고, 나의 질문에 그것을 적응시켰다. 다시 한번 감사드립니다. –

+1

@Jim_Bo : 나는 이것이 덜 혼란 스럽다고 생각했지만 두 가지를 결합 할 것입니다. –

+0

@Sinan, 원본 답변도 올릴 수 있습니까? 약간의 차이가 있었지만 학습 곡선에 도움이되었습니다. 감사. –

6

당신은 매번 파일 경로를 얻지 말라고 이야기합니다. 프로그램 단계를 구획화하지 않았기 때문일 수 있습니다.

일반적으로 이러한 종류의 프로그램을 단계별로 나눕니다. 초기 단계 중 하나는 데이터 유효성 검사입니다. 프로그램을 계속 진행하기 전에 가능한 모든 데이터의 유효성을 검사합니다. 그 중 하나라도 내가 예상 한 것과 맞지 않는다면, 나는 프로그램을 계속하도록 내버려 두지 않는다. 나는 무언가가 잘못되었음을 발견하기 위해 중요한 것을 (데이터베이스에 물건을 넣는 것과 같은) 중요한 것을 통해 절반을 얻고 싶지 않습니다.

데이터를 가져올 때 데이터를 모두 확보하고 새 데이터 구조에 값을 저장하십시오. 그 후에 원래 데이터 나 CGI 함수를 사용하지 마십시오. CGI 모듈은 프로그램에 데이터를 전달하기위한 것입니다. 그 후 나머지 프로그램은 가능한 한 CGI에 대해 거의 알지 못합니다.

저는 여러분이하고있는 일을 잘 모릅니다. 그러나 실제 파일 이름을 입력으로 사용하는 것은 거의 항상 디자인 냄새입니다.

+0

나는 "Design Smell"이라는 단어를 사용해야했다. 좋은 말씀입니다. http://c2.com/cgi/wiki?DesignSmell – ddoxey