Perl은 정규 표현식이 깊은 수준에서 통합된 언어 중 하나입니다. 주요 교체 연산자는 s///로, 이는 패턴에 따라 문자열의 조각을 검색하고 변경하는 데 사용됩니다. 이 구조에는 특히 탐욕적/게으른 패턴, 다중 행 처리 및 교체 옵션 작업 시 여러 미세한 사항이 숨어 있습니다.
s/// 연산자는 Perl의 초기 버전부터 존재하며, Perl은 이후 다른 언어들이 채택한 정규 표현식 구문 기본을 설정했습니다. 패턴 구성 및 수정자(g, m, s, i, x 등)의 대부분의 미세한 사항들은 Perl에서 발전했습니다.
실제로 많은 개발자들이 탐욕적 수량자를 잘못 사용하거나 수정자(특히 s와 m)를 혼동하여, 다중 행 텍스트나 대용량 데이터에서 교체 시 예상치 못한 결과를 초래합니다. 문자열에서 하나의 일치 항목을 기대할 때 다른 것이 반환되거나, 첫 번째/마지막 발생만 교체될 수 있습니다.
패턴을 올바르게 선택하고 설정하는 것이 중요하며, 수정자의 작동 방식을 이해해야 합니다. 탐욕적 패턴(예: .*)은 가능한 최대 범위를 캡처하고, 게으른 패턴(예: .*?)은 최소한 필요한 범위를 캡처합니다.
수정자 작업:
g — 모든 일치 항목에 대해 교체를 수행합니다.s — 다중 행 문자열 처리를 포함하여, 여기서 점(.)은 줄 바꿈 문자를 캡처합니다.m — ^ 및 $ 기호의 동작을 변경합니다.예: 태그 <tag> ... </tag>를 한 번에 하나의 태그만 스페이스로 교체하기 (게으른):
my $text = 'a <tag>1</tag> <tag>2</tag> b'; $text =~ s/<tag>.*?<\/tag>//g; print $text; # a b
다중 행 문자열 처리:
my $data = "Line 1 Line 2 <tag> DATA </tag> End"; $data =~ s/<tag>.*?<\/tag>//gs; print $data;
주요 특징:
s는 점(.)이 줄 바꿈을 캡처하게 합니다.g는 수행된 교체의 수에 영향을 미칩니다.여러 태그를 처리할 때, 탐욕적 . 뒤에 ?를 명시하지 않으면 어떻게 되나요?*
탐욕적 수량자는 가능한 최대 범위를 캡처하게 되며, 중간 태그를 포함하게 되어 예상치 못하게 첫 번째 <tag>와 마지막 </tag> 사이의 모든 것을 삭제합니다:
my $txt = 'A <tag>1</tag> <tag>2</tag> B'; $txt =~ s/<tag>.*<\/tag>//g; print $txt; # A B
여기서 첫 번째 <tag>와 마지막 </tag> 사이의 모든 부분이 교체되었습니다.
Perl의 정규 표현식에서 m 수정자와 s 수정자의 차이점은 무엇인가요?
s — 점(.)이 줄 바꿈 문자를 캡처합니다; m — 다중 행 텍스트 내에서 ^와 $의 작업을 변경합니다. 이들의 용도는 다르지만 종종 헷갈립니다.
my $s = "abc def"; # /^def/는 m 없이 작동하지 않습니다. print $s =~ /^def/m; # 1 (true)
s///를 단 한 번만 적용하여 패턴의 모든 발생을 처리하는 방법은 무엇인가요?
g 수정자가 없으면 첫 번째 발생만 교체됩니다. 글로벌 교체를 위해 g를 추가해야 합니다:
my $s = "foo bar foo"; $s =~ s/foo/baz/g; # 두 번 모두 foo를 교체합니다.
개발자가 HTML 태그 교체를 이렇게 작성하는 경우:
$text =~ s/<tag>.*<\/tag>//g;
결과적으로 모든 태그와 그 사이의 내용이 삭제됩니다 — 각각 따로가 아니라.
장점:
단점:
게으른 패턴과 올바른 수정자를 사용하는 것이 좋습니다:
$text =~ s/<tag>.*?<\/tag>//gs;
장점:
단점: