프로그래밍Fullstack 개발자

Perl 정규 표현식에서 양의 수량자에 대한 느린 처리와 탐욕적인 처리 원리를 설명하십시오. 이것이 문자열 구문 분석에 어떤 영향을 미칩니까? 미묘한 점과 비정상적인 동작의 예를 제시하십시오.

Hintsage AI 어시스턴트로 면접 통과

답변.

Perl의 정규 표현식에서 수량자 *, +, ?, {n,m}는 기본적으로 탐욕적 (greedy)입니다: 이는 패턴에 일치하는 최대한 많은 문자를 캡처합니다.

수량자 뒤에 ?를 추가하면 느린 (lazy 또는 non-greedy)으로 바뀌며: 이는 정규 표현식이 일치하는 데 필요한 최소한의 문자를 캡처합니다.

탐욕적 일치 예:

my $str = 'foo <bar> baz <quux>'; $str =~ /<.*>/; # '<bar> baz <quux>'를 캡처합니다.

느린 일치 예:

my $str = 'foo <bar> baz <quux>'; $str =~ /<.*?>/; # '<bar>'를 캡처합니다.

특징:

탐욕적 표현식은 HTML 및 기타 중첩 구조를 구문 분석할 때 예상보다 더 많은 내용을 "먹어버릴" 수 있습니다!


트릭 질문.

<a><b><c> 문자열을 구문 분석할 때 다음 두 정규 표현식은 어떻게 다릅니까: /<(.*)>//<(.*?)>/?

답변:

  • /<(.*)>/ (탐욕적)은 최대 블록을 캡처합니다 — 일치: <a><b><c>
  • /<(.*?)>/ (느린)은 첫 번째 그룹만 캡처합니다: <a>

예:

my $s = '<a><b><c>'; $s =~ /<(.*)>/; # $1: 'a><b><c' $s =~ /<(.*?)>/; # $1: 'a'

주제의 미묘한 점을 모르고 발생한 실제 오류의 예.


이야기

뉴스 헤드라인을 가져오는 어플리케이션에서 프로그래머는 /\<(.*)\>/를 사용하여 <title>뉴스</title> 문자열에서 태그 이름을 구문 분석하고자 했습니다. 결과적으로 정규 표현식은 첫 번째 <와 마지막 > 사이의 전체 문자열을 캡처하여 필요한 요소가 아니라 전체를 가져왔습니다. 중첩 태그가 생기자 오류가 발견되었습니다.


이야기

인용된 문자열을 구분하기 위한 논리 구문 분석기에서 사용된 패턴 /"(.*)"/는 예상하지 못하게 첫 번째와 마지막 따옴표 사이의 모든 것을 캡처했습니다. 따라서 마크업이 잘못 분할되었고, 패턴을 /"(.*?)"/로 교체할 때까지 문제가 지속되었습니다.


이야기

따옴표를 포함할 수 있는 CSV 자동 파서에서 "탐욕적"으로 잘못된 패턴이 작성되어 여러 열이 하나로 합쳐졌습니다. 도입된 파서의 오류는 대량 데이터에서만 발견되었으며, 느린 패턴 수정이 문제를 해결했습니다.