2012-05-04 3 views
12

몇 분 전까지 만해도 Perl$은 모든 종류의 줄 끝과 일치한다고 생각했습니다. 불행히도, 내 가정은 틀린 것으로 드러났다.

다음 스크립트는 이라는 단어를 $string3에 대해서만 제거합니다.

use warnings; 
use strict; 

my $string1 = " match to the end" . chr(13); 
my $string2 = " match to the end" . chr(13) . chr(10); 
my $string3 = " match to the end" .   chr(10); 

$string1 =~ s/ end$//; 
$string2 =~ s/ end$//; 
$string3 =~ s/ end$//; 

print "$string1\n"; 
print "$string2\n"; 
print "$string3\n"; 

는하지만 난 $ 적어도 chr(13).chr(10) 일치하는 경우를 본 적이 거의 75 % 확신합니다.

따라서 정확히 $ 아톰이 일치합니까? \n/chr(10)하지 전에 \r/chr(13) 전에

+3

': crlf' 모드에서 파일을 읽었을 수 있습니다. 따라서 파일에'chr (13) .chr (10)'이 있지만 일치하는 문자열에는'chr (10)'만있었습니다. – cjm

답변

5

$ 일치하는 경우에만 위치.

newline 문자 전에 대다수의 문자가 잘못 해석되는 경우가 종종 있지만 (문제가되지 않는 경우가 많은데) "라인 피드"문자 보다 먼저 일치하지만 캐리지 리턴 문자 이전에는 일치하지 않습니다.

Regex Tutorial - Start and End of String or Line Anchors을 참조하십시오.

+1

새 줄 바꿈 규칙. –

+1

사실. '개행 문자 '같은 것은 없습니다. – Borodin

+0

@ 보 로딘, 유니 코드 동의하지 않습니다. U + 000A는 LINE FEED와 NEW LINE을 포함한 몇 가지 이름으로 알려져 있습니다. – ikegami

12

먼저 /m 수정자가 효과적인지 여부에 따라 다릅니다.

/m이 활성화되면 \n 문자 앞에 또는 해당 문자열의 끝에 일치합니다. (?=\n|\z)과 같습니다.

/m이 없으면 문자의 마지막 문자 또는 문자열 끝에있는 문자는 \n 문자 앞에 일치합니다. (?=\n?\z)과 같습니다.

일반 개행과 일치하지 않습니다. \R 메타 문자 (5.10.0에서 도입)는이를 수행합니다 (그러나 end-of-string 속성은 $이 아닙니다). 이전 동등성 중 하나에서 \n\R으로 대체하면 일반 개행과 일치하는 $이 작동합니다.

\n이 항상 chr(10) 인 것은 아닙니다. 플랫폼에 따라 다릅니다. 현재 사용중인 대부분의 플랫폼은 \n이고, 의미는 chr(10)입니다. 그러나 항상 그런 것은 아닙니다. 예를 들어 구형 Mac의 경우 \nchr(13)이고 \rchr(10)이었습니다.

+4

대답의 후반 부분은 단순히 사실이 아니더라도 오도 된 것입니다. 내부적으로 Perl *은 * 항상 *'* chr (10) 또는 ASCII''LF '인 플랫폼의 행 끝 시퀀스를' "\ n"'으로 나타냅니다. 이는 Linux 및 Max OS X 용 외부 파일에 나타나는 것과 동일하지만 여분의 IO 계층은 Windows 및 DOS 플랫폼에서 'CR LF'와, 그리고 Mac OS v9 및 이전 버전에서는 'CR'과 변환합니다. ''\ r "'는'chr (13)'또는 ASCII'CR' 이외의 다른 것이 아니 었습니다. – Borodin

+0

@Borodin 그러나 다른 플랫폼에서 생성 된 파일을 처리해야하는 경우주의해야합니다. –

+2

@ 보리 든, 틀렸어 cjm이 맞습니다. MacOS 빌드에서는 \ n과 \ r이 각각 0D와 0A를 매치/생성했습니다. 그래서'\ x0D \ x0A'를'\ r \ n' 대신에 CGI 출력으로 사용하는 것이 좋습니다 (obselete). 당신이 말하는 것이 사실이라면, 그 두 가지는 동등한 것입니다. 당시 PerlIO 계층은 존재하지도 않았습니다. – ikegami

1
/$/ 
/$/m 

각각

/(?=\n\z)|\z/ 
/(?=\n)|\z/ 

동등하다. \n은 모든 기존 플랫폼에서 U + 000A (라인 피드 일명 NEWLINE)와 일치합니다.

+0

당신의 동등한 정규 표현식이 쓰여진대로 맞지만, 제 버전이 더 좋습니다. '\ z'는 제로 너비 어설 션이기 때문에'(? = ...)'안에 있는지 여부는 중요하지 않지만 그룹 내에서 교대를 움직이면 더 큰 정규 표현식으로 사용할 수 있습니다. 입니다. 버전에 따라,'| '(? : \ n \ z) | \ z)'를 사용하여'|'가 교대로 반복하지 않도록해야합니다. – cjm

관련 문제