텍스트 및 일상 도구 · 텍스트 도구 키트
Kleene에서 JavaScript까지: 정규 표현식의 간략한 역사
· 배경
정규식 자바스크립트 컴퓨팅 기록
1950년대 오토마타 이론부터 ed, grep, Perl을 거쳐 모든 브라우저의 JavaScript 버전에 이르기까지 정규식을 추적하여 구문이 왜 그렇게 보이는지, 어떤 기능이 언제 도착했는지 설명합니다.
모두가 반만 알고 있는 이상한 작은 언어 — 정규식 구문이 오래되고 일관성이 없는 것처럼 느껴지는 이유
정규식은 본질적으로 정규식이기 때문에 여러 시대에 걸쳐 조합된 언어처럼 느껴집니다. 교대, 반복 및 그룹화의 컴팩트 코어는 수학적 표기법에서 편집기 명령, 명령줄 필터 및 프로그래밍 언어 기능으로 성장했습니다. 구두점은 살아남았지만 각 호스트는 고유한 편의성, 제약 조건 및 용어를 추가했습니다.
이 기록은 패턴이 친숙해 보이지만 grep, Perl, Python 및 JavaScript 간에 다르게 동작할 수 있는 이유를 설명합니다. "Regex"는 하나의 범용 문법이 아닌 성입니다. 독학한 분석가에게 유용한 교훈은 모든 방언을 외우는 것이 아니라 빌린 패턴을 신뢰하기 전에 엔진, 플래그 및 교체 규칙을 식별하는 것입니다.
Kleene의 정기 이벤트 — 우리에게 별을 안겨준 1950년대 유한 오토마타 수학
유한 오토마타와 "정기 사건"에 대한 Stephen Cole Kleene의 연구는 1950년대 이론적 뿌리를 제공했습니다. 그의 표기법은 합집합, 연결, 종결 등의 연산을 사용하여 일련의 기호 시퀀스를 설명했습니다. 폐쇄 작업은 Kleene 별이 되었습니다. `A*`는 단순히 "한 번 이상 반복"하는 것이 아니라 A에서 가져온 0개 이상의 반복을 의미합니다.
유한 오토마타가 인식하는 공식 정규 언어는 현재 정규식 레이블로 판매되는 많은 구문보다 범위가 좁습니다. 예를 들어 역참조는 기존 모델 이상의 조건을 표현할 수 있습니다. 따라서 최신 엔진은 Kleene의 원래 수학적 개체를 뛰어넘는 기능과 실행 전략을 갖춘 패턴 언어를 구현하면서 역사적인 이름과 표기법의 대부분을 보존합니다.
Thompson, ed 및 grep — 1960년대 후반과 1970년대 초반 Unix 도구에서 regex가 텍스트 편집에 어떻게 도입되었는지
Ken Thompson은 이론을 실제 텍스트 도구에 연결했습니다. 그의 1968 Communications of the ACM 논문에서는 텍스트 검색을 위해 정규식을 기계어 코드로 컴파일하는 방법을 설명했으며, 그의 초기 편집 작업은 Unix 계통 내에서 패턴 일치를 배치하는 데 도움이 되었습니다. `ed` 편집기는 일치하는 줄을 선택하고 변환하는 명령에 정규식을 사용했습니다.
`grep` 이름은 일반적으로 `g/re/p`로 렌더링되는 `ed` 명령에서 유래되었습니다. 정규식과 일치하는 행을 전역적으로 선택하여 인쇄합니다. 초기 grep은 오늘날의 GNU 옵션 모음이 아니었으며 이후의 기본 및 확장 POSIX 형식은 다릅니다. 지속적인 변화는 실용적이었습니다. 작은 기호 언어가 텍스트를 찾기 위한 일상적인 인터페이스가 되었습니다.
Perl 및 PCRE — 탐욕스럽지 않은 수량자, 둘러보기 및 오늘날 대부분의 도구가 복사하는 구문을 추가한 확장입니다.
Perl은 범용 프로그래밍의 중심이 되는 보다 풍부한 패턴 언어를 만들었습니다. 버전 전반에 걸쳐 프로그래머는 눈에 잘 띄는 하나의 생태계에서 캡처 그룹, 역참조, 어설션, 게으른 수량자 및 패턴 수정자를 접했습니다. Perl 5 문서는 이전 Unix 형식에는 없는 많은 기능과 함께 최소 일치를 위한 `*?` 및 긍정적인 예측을 위한 `(?=...)`와 같은 구성을 기록합니다.
Perl이 모든 확장 기능을 발명했다고 생각하기보다는 Perl이 이 스타일을 대중화했다고 말하는 것이 더 안전합니다. PCRE는 의도적으로 Perl 호환 구문을 제공했지만 다른 엔진은 선택된 아이디어를 채택하고 다른 엔진은 거부했습니다. 공유 구두점은 다양한 의미, 유니코드 동작 또는 성능을 숨길 수 있습니다. 결과적으로 “Perl과 유사하다”는 것은 Perl 패턴의 이식성을 보장하는 것이 아니라 광범위한 영향력을 설명하는 것입니다.
Perl은 더 큰 실용적인 패턴 언어를 대중화했습니다. 나중에 엔진을 선택적으로 빌림
JavaScript는 브라우저 및 기타 ECMAScript 환경에서 실행되는 프로그램을 위해 자체 `RegExp` 객체와 `/pattern/gi`과 같은 리터럴 구문을 표준화했습니다. 그 특징에는 캡처 및 비캡처 그룹, 역참조, 예측, 게으른 수량자 및 문자 클래스가 포함됩니다. 이후 버전에서는 ES2018 사양에 명명된 캡처 그룹 및 Lookbehind 어설션이 추가되었습니다.
JavaScript는 구분 기호가 다른 PCRE 또는 Python이 아닙니다. 기능 가용성은 엔진에 의해 구현된 ECMAScript 버전에 따라 다르며 플래그는 장식이 아닌 동작의 일부입니다. MDN의 정규식 가이드는 브라우저 구문에 대한 관련 실무 참조이지만 유효한 JavaScript 예제라도 특정 인터페이스가 노출하지 않는 플래그에 의존할 수 있습니다.
JavaScript는 ES2018에서 명명된 그룹과 뒤돌아보기를 얻었지만 엔진과 플래그는 여전히 다릅니다.
브라우저는 일반 텍스트 작업 근처에 JavaScript 정규 표현식 엔진을 배치합니다. 페이지는 특수 정규식 서비스에 텍스트를 보내지 않고도 패턴을 컴파일하고 일치 항목 수를 계산하여 `String.prototype.replace`에 전달할 수 있습니다. 이러한 가용성으로 인해 브라우저 측 찾기 및 바꾸기 인터페이스가 가능해졌지만, 더 광범위한 개인정보 보호 주장을 위해 주변 페이지를 별도로 검사해야 합니다.
ToolAcre의 구현은 `compilePattern` 내에서 `new RegExp`을 호출하고 컴파일 실패를 포착하고 던지는 대신 오류를 반환합니다. `findReplace`은 표준 교체 작업을 적용하기 전에 일치 항목을 계산합니다. 결과적으로 캡처 참조와 같은 JavaScript 대체 토큰은 호스트 문자열 API를 따릅니다. 정규식 구문과 대체 구문은 서로 관련되어 있지만 서로 다른 언어입니다.
여기서 다루지 않는 내용 — 기본을 넘어서는 형식적 언어 이론 및 엔진 성능 내부
이 짧은 기록은 실제 엔진과 유한 오토마타, 정규식 실행 알고리즘 조사 또는 속도별 구현 순위 지정 사이의 동등성을 입증하지 않습니다. 역추적, 선형 시간 기법 및 병리학적 패턴은 별도로 치료할 가치가 있습니다. ToolAcre 가드는 구문 오류를 포착하지만 과도한 역추적을 수행하고 기본 브라우저 스레드를 정지시키는 유효한 표현식을 감지하지 못합니다.
또한 타임라인은 모든 메타문자를 단일 발명자에게 할당하지 않습니다. 소프트웨어 기능은 한 번의 깔끔한 핸드오프가 아닌 논문, 편집자, 언어 릴리스 및 호환 가능한 재구현을 통해 제공되는 경우가 많습니다. 소스는 특정 이정표를 지원합니다. 그들은 하나의 제품이 현대 정규 표현식을 도매로 만들었거나 나중에 맛이 동일한 동작을 물려받았다는 단순한 이야기를 정당화하지 않습니다.
요점 — 텍스트 도구 키트의 정규식 모드는 JavaScript의 특징이므로 브라우저 문서의 패턴은 작성된 대로 작동합니다.
실용적인 상속은 ToolAcre에서 볼 수 있습니다. Regex를 켜면 검색 텍스트가 브라우저의 JavaScript 엔진에 의해 컴파일됩니다. Regex를 끄면 메타 문자가 이스케이프되어 검색 리터럴이 됩니다. 전체 단어는 ASCII 스타일 `` 경계로 표현식을 래핑하는 반면, 대소문자 구분은 `i` 플래그가 항상 존재하는 전역 `g` 플래그를 동반하는지 여부를 제어합니다.
마지막 세부 사항은 브라우저 문서 패턴이 작성된 대로 작동한다는 개요의 광범위한 약속을 수정합니다. ToolAcre는 여러 줄, 점 전체, 고정 또는 유니코드 플래그를 노출하지 않으므로 `m`, `s`, `y`, `u` 또는 `v`가 필요한 예는 조정이 필요하며 일부는 재현될 수 없습니다. 도구를 사용하여 지원되는 JavaScript 패턴을 테스트하고, 교체 횟수를 읽고, 다듬기 전에 실행 취소하세요.