... | perl -pe "s/([^$filespec]*)($filespec)/ ...
$filespec
따라서 대부분의 경우 위의 구조가 잘 작동하는 기능이 있습니다. 하지만파일 이름에 대시가 있는 경우메시지 를 받았습니다 Invalid [] range
.
$filespec
이러한 구문 분석 오류의 영향을 받지 않는 파일 이름으로 변수가 확장되도록 하려면 어떻게 해야 합니까 ?
답변1
주요 가정 - $filespec
일치시키려는 문자 집합입니다. 이것은아니요정규식.
일부 코드를 사용하여 이 문제를 시뮬레이션해 보겠습니다.
filespec = 'z-a'
perl -e 'print "MATCH\n" if "DEF" =~ /$filespec/'
use strict;
use warnings;
my $filespec = 'z-a';
print "Match\n" if "DEF" =~ m/[^$filespec]/ ;
달리기는 줄 수 있다
Invalid [] range "z-a" in regex; marked by <-- HERE in m/[^z-a <-- HERE ]/ at try line 6.
$filespec
문제는 정규식의 확장이 m/[^z-a]/
. 이 경우 z-a
문자 범위가 유효하지 않습니다.
이 문제를 해결하려면 (적어도) -
in 을 이스케이프 처리해야 합니다 $filespec
. 이것을 사용하면 quotemeta
다음과 같이 트릭을 수행할 수 있습니다.
use strict;
use warnings;
my $filespec = quotemeta 'z-a';
print "Match\n" if "DEF" =~ m/[^$filespec]/ ;
출력은 다음과 같습니다
Match
이를 파이프 명령 시뮬레이션에 포함합니다. 첫 번째는 실패한 명령 버전입니다.
filespec='z-a'
perl -e "print qq[MATCH\n] if 'DEF' =~ /[^$filespec]/"
달려가다
Invalid [] range "z-a" in regex; marked by <-- HERE in m/[^z-a <-- HERE ]/ at -e line 1.
이것은 고정 버전입니다.
filespec='z-a';
filespec=`perl -e "print quotemeta qq[$filespec]"`
perl -e "print qq[MATCH\n] if 'DEF' =~ /[^$filespec]/"
답변2
괄호 안에 있는 표현식의 대시는 백슬래시 1 로 이스케이프되거나 표현식의 첫 번째 또는 마지막 문자가 아닌 한 범위로 처리됩니다(또는 ^
다음 첫 번째 ^
또는 마지막 문자 쌍으로 표현되는 경우 수식이 부정됩니다).
예를 들어
[a-z]
a
from to의 모든 소문자 와 일치합니다 z
(단, 참고 2 참조).
[a\-z]
, [-az]
그리고 모두 , 및 [az-]
3개의 문자만 일치합니다 .-
a
z
그리고 @pmqs가 답변에서 지적했듯이 [z-a]
이는 잘못된 범위이므로 오류가 발생합니다.
정규 표현식에 하나 이상의 대시가 있는 대괄호 표현식이 포함된 경우 예상대로 작동하도록 수정해야 합니다. 대부분의 경우와 마찬가지로 사용 중인 소프트웨어와 언어 기능을 충분히 이해하여 원하는/기대하는 작업을 수행할 수 있어야 합니다.
man perlre
편의 기능과 알아야 할 기타 "문제점"을 포함하여 Perl 정규 표현식에 대해 자세히 알아보려면 리소스를 참조하세요 . 이 매뉴얼 페이지에는 많은 내용이 있으므로 한 번에 모두 이해할 수는 없습니다. 필요할 때 검토하면 앞으로 몇 년 동안 어떻게 작동하는지 더 많이 이해하게 될 것입니다. man perlrequick
빠른 참조 및 man perlretut
튜토리얼 도 참조하세요 . man perlrecharclass
Perl의 문자 클래스 및 대괄호 표현식 에 대한 추가 정보. man perlrebackslash
Perl의 백슬래시 및 이스케이프 시퀀스 에 대한 추가 정보.
man
(Linux 배포판이나 Unix에 페이지로 사용할 수 있는 Perl 문서가 없으면 perldoc
대신 run 명령을 사용하십시오 man
(예 perldoc perlre
: ).
Perl에는 총 54,000단어의 산문과 예제로 이루어진 5개의 주요 매뉴얼 페이지가 정규식 전용으로 있다는 점을 고려하면(그리고 두 개는 아마도 전혀 필요하지 않을 것입니다: perlreguts
Perl 정규식 엔진의 작동 방식을 설명하고 perlreapi
Perlre의 플러그인 인터페이스를 설명합니다), 당신은 이것이 복잡한 주제라고 추측하기 시작할 수도 있습니다. 그리고 당신이 옳을 것입니다.
노트:
1 모든 정규식 엔진이 대괄호 표현식 내에서 이스케이프 문자를 지원하는 것은 아닙니다 . Perl은 하지만 대부분은 그렇지 않습니다. 예를 들어 GNU grep의 BRE(기본값 또는 -G
) 및 ERE( -E
)는 그렇지 않지만 GNU grep의 perl 호환( -P
) 정규 표현식은 그렇습니다.
2 [[:alpha:]]
또는 일반 ASCII뿐만 아니라 유니코드 텍스트도 처리할 수 있으므로 일반적으로 알파벳 문자 일치에 더 적합합니다 [[:upper:]]
. 영숫자와 동일합니다.[[:lower:]]
[[:alnum:]]