본문으로 건너뛰기
yceffort
PostsSeriesTagsAbout🧪 Research
EN

Tweaks

theme
accent palette
film grain
minimal mode
BACK TO INDEX
◆ ESSAY
--min
--year
KOoriginal

mailMail icongithubtwitter
yceffort
•
© 2026
•
https://yceffort.kr
BACK TO INDEX
◆ ESSAY

알쏭 달쏭한 자바스크립트 정규식

avatar
yceffort
2021-03-21 · 3분
3min
2021year
KOoriginal
javascript

자바스크립트 정규식으로 숫자를 찾는 방법은 보통 아래와 같다.

const str = 'hello world, 123'
const digitRegex = /\d+/g

digitRegex.test(str) //true

그런데 코딩을 하던 중 한가지 이상한 일이 발생했는데, 대략 아래와 같은 모습이었다.

const digitRegex = /\d+/g

const result1 = digitRegex.test('hello 123')
const result2 = digitRegex.test('123')
const result3 = digitRegex.test('123')

console.log(result1) // true
console.log(result2) // false ???????????
console.log(result3) // true

정규 표현식에 전역 플래그를 설정한 경우, test() 메서드는 정규 표현식의 lastIndex (en-US)를 업데이트합니다. (RegExp.prototype.exec()도 lastIndex 속성을 업데이트합니다.)

test(str)을 또 호출하면 str 검색을 lastIndex부터 계속 진행합니다. lastIndex 속성은 매 번 test()가 true를 반환할 때마다 증가하게 됩니다.

참고: test()가 true를 반환하기만 하면 lastIndex는 초기화되지 않습니다. 심지어 이전과 다른 문자열을 매개변수로 제공해도 그렇습니다!

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test

조금더 자세히 살펴보자면, 대략 다음과 같다는 뜻이다.

const digitRegex = /\d+/g

console.log(digitRegex.lastIndex) // 0
const result1 = digitRegex.test('hello 123')

// test로 digitRegex의 index (9) 를 찾았으므로 업데이트 함
console.log(digitRegex.lastIndex) // 9
// 9 부터 다시 찾음. 그런데 못찾았으므로 초기화가 진행됨.
const result2 = digitRegex.test('123')

console.log(digitRegex.lastIndex) // 0
// 0 부터 다시 찾아서 숫자를 찾음.
const result3 = digitRegex.test('123')

정확히 왜 이렇게 구현했는지에 대해서는 찾을 수 없었다. 추측건데 정규식에 전역플래그가 있다는 것은 검색하려는 대상 str도 전역으로 쓰이는 용도일 것이고, 그 때문에 검색하는 str이 아예 다른 것이 온다는 가정을 하지 않았기 때문이 아닐까? (뭐래는거야?)

어쨌든 간에, 이를 올바르게 동작하게 만들기 위해서는 search를 쓰면 된다. 주의할 점은 .search는 string에 있는 메소드라는 것.

const digitRegex = /\d+/g

const result1 = 'hello 123'.search(digitRegex) > -1
const result2 = '123'.search(digitRegex) > -1
const result3 = '123'.search(digitRegex) > -1
const result4 = '바보'.search(digitRegex) > -1

console.log(result1) // true
console.log(result2) // true
console.log(result3) // true
console.log(result4) // false

관련 글

  • #turbopack#nextjs#bundler

    Next.js turbopack에서 싱글톤이 두 개가 됐다: scope hoisting 버그와 순환 import

    Next.js 16 turbopack 프로덕션 빌드에서 모듈 스코프 싱글톤이 런타임에 두 개가 됐다. 같은 동기 구간에서 조건 판정이 뒤집히고, 응답이 도착해도 타임아웃이 나는 증상을 번들 산출물로 추적한 기록. scope hoisting의 부분 병합, 순환 import, 이미 고쳐져 있던 upstream 버그, 그리고 뒤늦게 돌린 단일 변수 실험까지.

    2026-08-19·28분
  • #javascript#animation#web-animations-api

    number-flow를 구형 브라우저로 이식하기: 다섯 가지 결정과 두 가지 번복

    number-flow가 애니메이션을 켜는 최소 버전은 Chrome 125, Safari 17.2다. 이 하한을 Chrome 66과 WebKit 16.4까지 내리는 포크를 만들면서 내린 결정들과, 뒤집게 된 판단 두 가지, 그리고 자동 강등을 포기한 Safari 버그 조사의 기록.

    2026-08-11·44분
  • #nodejs#security#javascript

    Node.js vm 모듈의 함정: 샌드박스가 아닌 이유

    집필 중인 Node.js Deep Dive의 5.2장(vm 모듈의 함정) 일부를 미리 공개합니다.

    2026-02-27·25분
  • #nodejs#javascript

    Node.js Deep Dive (가제) 베타 리더를 모십니다.

    많관부22

    2026-02-19·5분

새 글을 놓치고 싶지 않으시다면 RSS로 구독해 주세요.

RSS 구독 →

yceffort — 프론트엔드 엔지니어입니다. 발표·기술 자문·기고 문의는 이곳에서 받고 있습니다.

← Back to the blogIssue on GitHub →