콘텐츠로 건너뛰기

정규식

JavaScript 정규식을 브라우저에서 실시간으로 테스트. 매치 강조, 캡처 그룹 확인, 모든 플래그 지원.

완전 무료 가입 불필요 브라우저 완결 5 개 언어 다크 모드
/ /

강조 결과

매치 상세

자주 쓰는 패턴

문제가 있거나 표시가 이상하면 다음으로 알려주세요: 문의 양식에서 알려 주세요.

📖 자주 걸리는 지점

JavaScript 의 정규식 엔진으로 패턴을 실시간으로 평가하고 매치 위치의 하이라이트와 캡처 그룹을 표시합니다. 처리는 브라우저 안에서 끝납니다. 쓰고 있는 것은 JavaScript 의 방언입니다여기서 통한 패턴이 PHP · Python · Go 에서 그대로 동작한다고는 할 수 없습니다. 문자 클래스의 의미, lookbehind 의 유무, 유니코드의 취급이 언어마다 다르기 때문입니다.

사례 무슨 일이 일어나는가 어떻게 하면 되는가
g 플래그를 붙이면 두 번째 결과가 달라진다 g 플래그가 붙은 정규식 객체는 lastIndex 라는 상태를 갖습니다. 같은 객체로 test() 를 반복하면 지난번 매치 위치부터 찾기 시작하므로 같은 문자열에 대해 truefalse 가 번갈아 돌아옵니다. 이것이 치명적이 되는 것은 정규식을 모듈의 최상위에서 정의해 돌려 쓸 때입니다 — 상태가 요청을 넘어 남아 가끔 검증을 통과해 버린다는 재현되지 않는 버그가 됩니다. 테스트에서는 한 번밖에 부르지 않으므로 우선 알아챌 수 없습니다. test()exec() 로 쓰는 정규식에 g 를 붙이지 마세요 — 전부에 매치시키고 싶다는 의도로 붙이기 쉽지만 test() 는 하나라도 있는가를 보는 함수이므로 g 는 불필요합니다. 전건을 얻고 싶다면 str.matchAll(re) 을 쓰세요(이쪽은 g 가 필수입니다). 돌려 쓰는 객체에서 g 가 필요하다면 호출 직전에 re.lastIndex = 0 을 넣으세요. 애초에 정규식 리터럴을 함수 안에서 매번 쓰는 비용은 무시할 수 있습니다 — JavaScript 엔진은 리터럴을 캐시하므로 공유를 피하는 편이 안전하고 속도도 거의 변하지 않습니다.
일본어나 이모지가 생각대로 매치되지 않는다 \w 는 ASCII 의 영숫자와 밑줄만을 의미합니다 — 일본어에는 일절 매치되지 않습니다. \b(단어 경계)도 같은 이유로 일본어 문장 안에서는 기대대로 작동하지 않습니다. 또 하나 심각한 것이 서로게이트 페어u 플래그를 붙이지 않으면 이모지나 일부 한자(𠮷 · 𩸽 등)가 두 글자로 다뤄집니다. 가 절반만 매치되고 [𠮷] 라는 문자 클래스는 두 서로게이트 중 하나라는 뜻 모를 집합이 됩니다. 글자 수 카운트나 잘라내기에서 글자가 깨지는 원인의 대부분이 이것입니다. u 플래그를 반드시 붙이세요 — 이것만으로 서로게이트 페어가 한 글자로 다뤄지고 나아가 \p{...} 라는 유니코드 프로퍼티를 쓸 수 있게 됩니다. 일본어라면 \p{Script=Hiragana} · \p{Script=Katakana} · \p{Script=Han} 입니다 — [ぁ-んァ-ヶ一-龠] 같은 범위 지정보다 정확하고 의도도 읽힙니다. 이모지를 다룬다면 \p{Extended_Pictographic} 이지만 피부색이나 가족 이모지는 여러 코드 포인트의 조합이므로 한 글자로 다루려면 Intl.Segmenter 가 필요합니다 — 정규식만으로는 한계가 있습니다. 글자 수를 세는 목적이라면 정규식이 아니라 Intl.Segmenter 를 쓰세요.
탐욕적 매치로 생각보다 넓게 잡힌다 .*가능한 한 길게 매치하려고 합니다. 따라서 <div>A</div><div>B</div> 에 대해 <.*> 를 걸면 < 부터 마지막 > 까지 전체가 하나의 매치가 됩니다. . 는 기본적으로 줄바꿈에 매치되지 않으므로 여러 줄이면 멈추지만 s 플래그를 붙인 순간 파일 전체를 삼킵니다. 이 동작은 올바르지만 기대와 어긋나면 테스트에서는 통과하고 프로덕션의 긴 입력에서 깨지는 형태로 나옵니다. 비탐욕의 .*? 로 하거나 더 좋게는 [^>]* 처럼 거기에 나타나지 않는 문자로 쓰는 것입니다 — 후자는 백트래킹이 일어나지 않으므로 빠르고 의도도 명확해집니다. 다만 더 근본적인 조언으로 HTML 을 정규식으로 파싱하지 마세요 — 속성값 안의 >, 주석, CDATA, 중첩된 같은 이름의 태그에서 반드시 무너집니다. 브라우저라면 DOMParser, 서버라면 각 언어의 HTML 파서를 쓰세요. 정규식이 맞는 것은 행 단위이고 구조를 갖지 않으며 서식이 정해진 텍스트입니다 — 로그의 행, 설정 파일의 한 줄, 식별자의 서식 검증. 중첩이 있는 구조는 정규식의 수비 범위 밖입니다.

중첩된 수량자는 ReDoS 의 온상입니다. (a+)+$(\w+\s?)*$ 처럼 반복 안에 반복이 있는 식은 매치되지 않는 입력에 대해 지수 시간이 걸립니다 — 30 자 정도의 입력으로 서버의 CPU 가 몇 분간 100% 가 됩니다. 얄궂게도 이것이 가장 많이 발견되는 것은 엄밀한 메일 주소 검증의 정규식이며 실제로 대규모 서비스의 장애 원인이 된 사례가 여럿 있습니다. 대책은 세 가지 — 중첩된 수량자를 쓰지 않는다, 입력의 길이에 상한을 둔다, 그리고 백트래킹하지 않는 엔진(Go 의 표준 regexp, Rust 의 regex, C++ 의 RE2)을 쓴다는 것입니다. 방언의 차이도 짚어 두세요 — JavaScript 에는 \A\z 가 없습니다(m 플래그 없는 ^ $ 로 대체합니다). lookbehind 는 ES2018 에서 들어왔지만 Safari 의 대응이 16.4 로 늦었으므로 오래된 환경을 대상으로 한다면 피하세요.

📖 사용법

  1. 1
    패턴 입력
    정규식을 입력하고 플래그를 토글합니다.
  2. 2
    테스트 텍스트 붙여넣기
    대상 문자열을 붙여넣으면 매치된 부분이 실시간으로 강조됩니다.
  3. 3
    캡처 그룹 확인
    오른쪽 패널에 각 매치의 위치와 캡처 그룹 값이 표시됩니다.

❓ 자주 묻는 질문

어떤 정규식 엔진을 사용하나요?
브라우저의 JavaScript 엔진을 사용합니다.
일본어 문자 클래스를 사용할 수 있나요?
예. Unicode 속성 이스케이프를 사용할 수 있습니다.
성능은 어느 정도인가요?
JavaScript 엔진을 직접 사용하므로 빠릅니다.
다른 언어의 코드로 변환할 수 있나요?
"코드로 복사" 메뉴에서 각 언어용 코드를 출력할 수 있습니다.
🐛 이 도구에서 문제가 발생했나요?

무료 · 가입 불필요. 재현 절차만이라도 도움이 됩니다. 보고는 운영자에게 직접 전달되어 개선에 사용됩니다.

※ 재현을 위해 브라우저 정보 (UA / 화면 / 언어 / URL) 가 자동 전송됩니다