한 정규식, 여러 구현체
정규식은 1950년대 이론 컴퓨터 과학에서 시작해 Unix를 거쳐 야생으로 나왔어. 이후 구현체마다 기능을 더하거나 빼면서 방언이 갈라졌지. 자주 만날 계열은 대략 넷이야.
PCRE(Perl-Compatible). 역참조, 전후방 탐색, 재귀, 소유적 수량자, 이름 붙은 그룹처럼 기능이 풍부한 계열이야. PHP와 PCRE2 사용 환경이 대표적이지. Python, Java, JavaScript, .NET도 비슷한 기능을 일부 제공하지만 PCRE와 같은 엔진은 아니야.
POSIX BRE / ERE. Unix의 오래된 계열이야. grep 기본은 BRE이고 egrep과 grep -E는 ERE를 써. ERE는 그룹화할 때 백슬래시를 쓰지 않고 전후방 탐색도 없지만 호환성이 아주 높아.
ECMAScript / JavaScript. PCRE와 닮았지만 독특한 점이 있어. 소유적 수량자가 없고, g와 y 플래그는 lastIndex를 통해 상태를 기억해. 후방 탐색은 비교적 늦게 추가됐어.
RE2 / Go. 유한 오토마타 계열로 입력 길이에 비례해 끝나도록 설계됐어. 역참조와 전후방 탐색을 지원하지 않는 대신 파국적 백트래킹으로 인한 ReDoS를 피할 수 있지.
엔진 방언 차이가 무는 자리
실제로 쓸 기능의 80%는 어디서나 통해. 구현 차이가 드러나는 자리는 이쪽이야.
- 후방 탐색 — 어떤 엔진은 고정 길이만 받고, 어떤 엔진은 가변 길이도 받아. RE2와 Go는 아예 지원하지 않아.
- 이름 붙은 그룹 — Python은
(?P<name>...), .NET·PCRE·JavaScript는(?<name>...)형태를 써. - 역참조 — PCRE·Python·JavaScript는 지원하지만 RE2는 지원하지 않아.
- 소유적 수량자 —
*+,++,?+는 PCRE와 Python 3.11+에서 되지만 JavaScript에는 없어. - Unicode — Python의
\w는 기본적으로 Unicode를 인식해. JavaScript의/u는 코드 포인트와 Unicode 속성 이스케이프를 올바르게 처리하지만\w에 한글을 포함하지는 않아.grep동작은 로캘과 구현에 따라 달라.
트랙 6에서는 도구별 차이를 더 자세히 비교해. 한 환경에서 되던 패턴이 다른 곳에서 실패하면 엔진과 버전, 플래그, 호스트 언어의 이스케이프부터 비교해.