2023. 5. 17. 15:30

정규식을 사용할 때 테스트로 다음과 같은 사이트들을 이용합니다.

regexr.com

regex101.com

 

 

1. 문제의 발견

다음과 같은 정규식을 만들면 아래와 같은 결과가 나옵니다.

/\{\{[test001]+:[a-zA-Z0-9]+\}\}|\{\{[test001]+\}\}/g


//테스트용 텍스트
{{test001}}, {{test001:test1}}

 

그런데 이걸 자바스크립트에 넣으면 아래와 같이 하나만 적중되는 현상이 일어납니다.

//let sReg = "/\{\{[test001]+:[a-zA-Z0-9]+\}\}|\{\{[test001]+\}\}/g";//결과 : null
let sReg = "\{\{[test001]+:[a-zA-Z0-9]+\}\}|\{\{[test001]+\}\}/g";

let reg = new RegExp(sReg);

console.log("{{test001}}, {{test001:test1}}".match(reg));

 

 

2. 원인 및 해결 방법

자바스크립트의 정규식을 문자열로 사용할 때 플래그는 적용되지 않습니다.

그래서 'RegExp'개체를 만들 때 글로벌 플래그를 설정해야 합니다.

let sReg = "\{\{[test001]+:[a-zA-Z0-9]+\}\}|\{\{[test001]+\}\}";

let reg = new RegExp(sReg, "g");
		
console.log("{{test001}}, {{test001:test1}},".match(reg));

 

혹시 'RegExp.exec'를 사용하고 있나요?

'RegExp.exec'는 적중된 정보를 한 개씩 출력합니다.

그래서 'RegExp.exec'를 사용하려면 반복하여 호출해야 합니다.

(참고 : MDN - RegExp.prototype.exec() )

let sReg = "\{\{[test001]+:[a-zA-Z0-9]+\}\}|\{\{[test001]+\}\}";

let reg = new RegExp(sReg, "g");

let arrResult;

while ((arrResult = reg.exec("{{test001}}, {{test001:test1}},")) !== null) 
{
	console.log(arrResult);  
}

 

 

3. 리터럴 사용

많은 언어가 문자열 정규식에 플래그를 넣어도 동작하기 때문에 하기 쉬운 실수입니다.

 

자바스크립트에서는 문자열이 아닌 정규식 리터럴일 때만 플래그가 동작합니다.

var sReg = /\{\{[test001]+:[a-zA-Z0-9]+\}\}|\{\{[test001]+\}\}/g;

var reg = new RegExp(sReg);

console.log("{{test001}}, {{test001:test1}}".match(reg));

 

 

마무리

참고 : MDN - 정규 표현식

 

다른 언어나 정규식 테스트 사이트에서는 문제가 없는데

자바스크립트에서만 앞에 한 개만 적중했다 하면 거의 이 문제입니다.

 

p.s. 예전에는 문자열에 플래그 넣어도 한 개 데이터는 나왔던 거 같은데....

예제 만들다 보니 그냥 null이 나오는군요.