본문 바로가기

잡담

Perl에서 newline 매칭하기

어제 새벽에, inureyes님이 갑자기 메신저로 말을 걸으신 게 화근이었다. Tattertools 1.1 Development Alpha 버전을 릴리즈하기 위해서, 간단한 코드 최적화를 하시는 모양이었는데, php 코드에서 쓸모 없는 php 구분 영역 기호 열기/닫기를 없애려고 하시는 거였다.

원래 의도했던 바는
... ?>
<? ...
과  같은 형태를 없애 앞뒤를 한 줄로 이어버리는 것이었다. 당연히, 패턴에는 newline이 포함됐다.
이것을 inureyes님은 find . -name "*.php" -exec perl -pi -e "/\?>\n<\?//" {} \;이라는 쉘 명령어로 하려고 하셨는데 계속 안 되고 있었던 것이다. (위 명령어의 내용을 해석하면, 현재 디렉토리와 그 하위 디렉토리 안의 모든 php 파일들에 대해서 perl을 이용해 저런 패턴 치환을 수행하라는 뜻이다)

newline을 perl 정규표현식에서 표현하는 방법이 잘못됐나 해서 한참 뒤져봤으나 그건 아니었고.. 일단 저 명령어 자체가 맞는지 알아보려고 다른 임의의 패턴을 만들어 써본 결과 저 명령어 자체는 잘 동작하고 있었다.

그래서 왜 그럴까 하고 한참 뒤져보고, #gnome 채널에도 가서 사람들한테 물어보고 그랬는데, 누군가 /s라는 옵션을 붙여보라고 했다. 그게 뭔가 찾아봤더니(man perlre) 전체 입력 문자열을 한 줄인 것처럼 해석하게 하는 것인데, 다른 건 다 똑같고 단지 정규표현식에서 "임의의 한 글자"를 나타내는 .이 newline도 매칭하도록 만드는 역할이었다. (보통 perl로 패턴 치환을 할 때 줄 단위로 하기 때문이다)

근데, 문제는 그래도 안 된다는 거였다.

도대체 왜 그럴까 하면서 삽질 끝에, newline이 패턴의 맨 끝(/pattern/replacement/option 형태로 쓰는데, 두번째 / 앞에 \n이 오는 경우)에 있으면 matching 및 치환이 잘 이루어지는데, 패턴의 중간에 있으면 안 된다는 것을 알 수 있었다.

왜 그럴까? ㅠㅠ Perl의 버그가 아닐까 하는 추측도 해보고 있지만, 이미 수많은 사람들에 의해 오랫동안 사용되어 온 perl에서 이렇게 쉽게 발견될 만한 버그가 있을 것 같지도 않고.. IRC에서는 래리월에게 물어보라는 얘기까지 나왔다.; 결국 원인은 아직 못 찾았고...

고로, 아시는 분은 좀 알려주세요~! -_-;

태그

  • 디토 2006.08.14 19:47

    \\n으로 해도 안될까요? :)

  • 이옹 2006.09.20 08:24

    나도 비슷한 문제 때문에 xml 해석기 짜다 다 엎었던 적이 있지; 정규표현식으로 찾아서 값 읽어들이는 편한 방식을 취하려고 했는데 결국 한글자씩 읽는 하드코어한 방식으로 노선변경..

    • daybreaker 2006.10.07 01:58 신고

      한 글자씩 읽기(....)..
      예전에 HTML 파서 만든답시고 Visual Basic으로 그런 삽질을 했던 기억이 나는군요. (나름 꽤 잘 돌아가는 파서였는데 OOP 지원 부족으로 클래스 계층구조화 실패하면서 꼬이기 시작하는 바람에 gg...)

  • alexken 2007.01.20 01:59

    의도하신 내용은 "/\\?>\\n<\\?//" 이 아니라
    "s/\\?>\\n<\\?//g" 이 아니었나 싶습니다.

    • daybreaker 2007.01.21 20:17

      흠.. 그런 방식은 vi에서만 쓰는 것인줄 알았는데.. 생각해보니 g 옵션을 붙일 수도 있겠군요. 나중에 다시 해봐야겠습니다.

  • nz 2010.03.15 21:14

    perl pie 옵션이 한줄에 하나씩 처리하라 라는 명령이기 때문에 perl 이 한줄을 읽고 거기서 할만한 정규표현 치환을 다 하고 다음줄 읽고 뭐 이런식으로 한줄씩 하기 때문이 아닐까요;

  • nike shoes 2013.07.23 07:18

    귀를 기울여봐 가슴이 뛰는 소리가 들리면 네가 사랑하는 그 사람 널 사랑하고 있는거야.