기초 & 활용

[JavaScript] 같은 정규표현식(RegExp) test 결과가 서로 다른 경우

JavaScript에서 다음 RegExp.prototype.test 구문을 이용하여 정규표현식을 검증하려 할 때가 있습니다.

const regex = /hello/g;

console.log(regex.test('hello'));
console.log(regex.test('hello'));

위 예시에서 정규표현식의 내용과 확인할 문자열이 모두 같기 때문에 두 로그의 값은 true가 나와야 할 것입니다. 하지만 실제 결과는 다음과 같이 표시됩니다.

true
false

아이러니하게도 두번째 실행 결과가 false로 나타났습니다.

원인과 해결 방법

이 문제는 정규표현식에 g 플래그를 달았을 때 발생하는 문제입니다. 간단하게 g플래그를 제거하면 문제가 해결됩니다.

const regex = /hello/;

console.log(regex.test('hello')); // true
console.log(regex.test('hello')); // true

정규표현식의 g 플래그는 표현식을 만족하는 하나 이상의 값을 찾습니다. 즉 문자열에서 일치하는 값을 찾게 된 시점의 포지션(lastIndex)을 기억하고 있으며, 다음 검증 시 해당 인덱스로부터 검색을 수행합니다.

const regex = /hello/g;

console.log(regex.test('hello')); // true
console.log(regex.lastIndex); // 5

console.log(regex.test('hello')); // false
console.log(regex.lastIndex); // 0

console.log(regex.test('hello')); // true
console.log(regex.lastIndex); // 5

위 예시에서 확인할 수 있듯이 처음 검색을 수행한 후에는 마지막 인덱스 위치가 5를 가리키고 있는 것을 확인할 수 있습니다. 이제 다음 검색은 lastIndex의 값으로부터 검색을 수행하는데, 이 때 정규식에 일치하는 값이 없으므로 false를 반환하게 됩니다. false가 반환되면 다시 lastIndex값은 0으로 초기화됩니다.

결국 이로인해 동일하지 않은 값이 반복되어 나타나게 되는 것입니다. 단순히 여러 문자열을 하나씩 정규식을 통해 검증하려면 g플래그를 사용하지 않아야 합니다.

아니면 아래와 같이 매 과정 마다 lastIndex를 0으로 초기화해도 됩니다.

const regex = /hello/g;

console.log(regex.test('hello')); // true
regex.lastIndex = 0;

console.log(regex.test('hello')); // true
regex.lastIndex = 0;

이렇게하면 매번 처음 문자열의 포지션부터 검색을 수행하기 때문에 원하는 결과를 얻을 수 있게 됩니다.

JooTC

안녕하세요. 테크놀로지에 관심이 많은 블로거입니다.

Recent Posts

Zalgo 텍스트와 이를 방지하는 방법

인터넷 커뮤니티 사이트에서 게시글이나 댓글에 간혹 장난을 목적으로 작성된 특이한 글자를 볼 수 있습니다. 위…

1개월 ago

리눅스 kill, killall 명령어 – 특정 프로세스 종료하기

리눅스 명령어 - kill, killall 리눅스 kill 명령어는 특정 프로세스를 종료해주는 명령어입니다. 백그라운드에서 실행되고 있는…

1개월 ago

JavaScript typeof null이 ‘object’인 이유

JavaScript는 역사가 긴 스크립트 프로그래밍 언어입니다. 세월이 흐르면서 많은 자바스크립트 표준이 만들어졌고, 현재는 많은 문법적…

1개월 ago

Mocha Error: Resolution method is overspecified. 해결 방법

NodeJS 테스트 프레임워크인 Mocha는 비동기 테스트를 지원합니다. 간혹 특정 테스트 스크립트를 작성하고 실행하면 아래와 같이…

1개월 ago

윈도우 11 설치 시 Microsoft 계정 로그인 없이 로컬 계정 만들기

언제부턴가 윈도우 11을 처음 설치할 때 마이크로소프트(Microsoft) 계정 로그인을 강제로 요구하게 되었습니다. 물론 마이크로소프트 계정이…

6개월 ago

에어팟 프로 2 케이스 스피커 소리를 완전히 끄는 방법

애플 에어팟 프로 2 (AirPods Pro 2) 케이스에는 스피커가 내장되어 있습니다. 그런데 간혹 아무 것도…

9개월 ago