기존 작업자가 작업해 둔 코드가 있었고, 요구 조건에 따라 이슈가 전달되어왔다.
기존 코드
function addComma(value) {
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
요구 조건은 아래와 같았고..
1. 숫자 천 단위마다 콤마 추가
2. 소수점에서는 콤마 추가하지 않아야 함
기존 코드에서는 소수점에서도 콤마가 추가되고 있었다.
function addComma(value) {
return value.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ',');
}
잘되는 듯 했지만, 크로스브라우징 이슈가 있었다.
safari에서 흰페이지로 뜨는 것이었다. 두둥..
그리고 SyntaxError: Invalid regular expression: invalid group specifier name 에러 메시지가 출력되고 있었다.
왜???
검토해보니, 정규식에 사용된 lookbehind 패턴 때문이었다.
정규식에는 두가지 알고리즘이 존재한다고 한다.
- Deterministic Finite Automaton (DFA): 문자열의 문자를 한번만 확인한다.
- Nondeterministic Finite Automaton (NFA): 최적의 일치를 찾을 때 까지 여러번 확인한다.
여기에서 자바스크립트는 NFA 알고리즘을 사용하고 있고 이 알고리즘의 동작으로 인해 Catastrophic Backtracking 가 일어날 수 있다고 한다.
regexp-catastrophic-backtracking 란?
오랜 시간 실행됨에 있어서 js 엔진이 중단되는 현상이라고 한다.
일반적인 증상으로 특정 문자열의 경우 CPU를 100% 사용하여 중단된다고 한다.
그리고 중단되기 때문에 화면에 아무것또 뜨지 않았던 것이다.(;;)
해결법으로는..
1. 조합의 수를 줄여서 순서대로 찾아 나가는 방식
2. 역 추적을 방지하는 lookahead 패턴으로 개발
두번째 방식을 권장한다고 한다.
정규식의 전방 탐색(Lookahead)과 후방 탐색(Lookbehind) 패턴에 대해 간단히 알아보면...
전방 탐색은 작성한 패턴에 일치하는 영역이 존재하여도 그 값이 제외되어서 나오는 패턴이고
후방탐색은 전방 탐색이 앞에 있는 문자열을 탐색하는 거라면 후방탐색은 뒤에 있는 문자열을 탐색하는 것이라고 한다.
이해가 잘 안되면 이 블로그 글을 읽어보자! (저는 이해에 도움이 많이되었습니다 -> https://blog.hexabrain.net/205)
즉, 처음에 수정한 정규식에서 (?<!\.\d*) 이 부분이 lookbehind에 해당하는 것이었다.
(1234.1234) <- 뒤의 문자열을 탐색
해결법을 찾기 위해 검색에 검색을 해봤고~!
정리가 잘되어있는 블로그 글을 발견했다!!! ㄳㄳ -> Javascript에서 천 단위 구분 기호로 쉼표가 있는 숫자를 인쇄하는 방법
그리고 선택한 방법들을 작성해보았다.!
1. split, join
function addComma(value) {
let splitVal = value.toString().split('.');
splitVal[0] = splitVal[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return splitVal.join(".");
}
2. replace function
function addComma(value){
return value
.toString()
.replace(/(\..*)$|(\d)(?=(\d{3})+(?!\d))/g, (digit, fract) => fract || digit + ',');
}
3. toLocaleString('ko-KR')
이때 maximumFractionDigits를 따로 수정하지 않으면 소수점 자릿수는 3으로 기본 값으로 출력된다.
(예시로 5로 바꾸어봤다)
function addComma(value) {
return value.toLocaleString('ko-KR', { maximumFractionDigits: 5 });
}
여러 방식을 알아보면서 정규식에 대해서 정말정말 공부하면 도움이 많이 되겠다고 생각한 하루였다.
인프런에 정규식 강의가 있던데,.ㅎㅎ..
참고!! (감사감사! 합니다.)
lookbehind 문법은 사파리와 익스플로러에서 쓸 수 없다.
'Javascript' 카테고리의 다른 글
(lodash) 값 타입에 따라 isUndefined, isEmpty 뭐를 써야할까? (0) | 2022.01.17 |
---|---|
CORS 에러를 해결하자, 어떻게? JSONP로! (0) | 2021.11.01 |
마우스로 창을 움직여보자! (0) | 2021.02.01 |
[jQuery기초] ajax (0) | 2020.06.30 |
[jQuery기초] 요소조작_이벤트_slice_trim_extend_each (0) | 2020.06.30 |
[jQuery기초] 요소조작_이벤트_replaceAll_replaceWith (0) | 2020.06.30 |
[jQuery기초] 요소조작_이벤트_animate_show&hide_css (0) | 2020.06.30 |
[jQuery기초] 요소조작_이벤트_width_innerWidth_height_innerHeight (0) | 2020.06.30 |