CSV를 JSON으로 바꿀 때 숫자로 둔갑하는 값 — 앞자리 0이 사라지는 문제
CSV 파일을 열어보면 모든 셀이 그냥 글자로만 보입니다. 콤마로 구분된 텍스트 한 줄일 뿐, "이 칸은 숫자다", "이 칸은 문자열이다" 같은 타입 정보는 파일 어디에도 적혀 있지 않습니다. 반면 JSON은 값의 타입을 명확히 구분하는 포맷이라서, {"zip":"05028"} 과 {"zip":5028} 은 완전히 다른 데이터입니다. 그래서 CSV를 JSON으로 바꾸는 변환기는 셀에 적힌 문자열을 보고 "이건 숫자 같으니 숫자로, 이건 문자열 같으니 그대로 두자"는 추측을 해야 합니다. 이 추측이 허술하면 우편번호·전화번호·사번처럼 앞자리가 0으로 시작하는 값에서 그 0이 통째로 사라지는 사고가 납니다.
1. 왜 "007"이 위험한 값인가
사람이 보기엔 "007"도 그냥 숫자처럼 보이지만, 이 값이 우편번호나 사원번호라면 앞의 0 두 개는 자릿수를 맞추기 위한 필수 정보입니다. 그런데 자바스크립트의 Number("007")은 그대로 7을 반환합니다. 만약 변환기가 "숫자로 파싱이 되면 숫자로 바꾼다"는 단순한 규칙, 즉 isNaN()이나 Number() 결과만으로 판단한다면 "007"은 소리 소문 없이 정수 7이 되어버리고, 원래 세 자리였던 값은 JSON에서 한 자리 숫자로 저장됩니다. 전화번호 "010-1234-5678"도 마찬가지 계열의 문제입니다. 이 값 자체는 하이픈이 섞여 있어 통짜 숫자로 파싱되진 않지만, 국번만 따로 "010"이라는 셀에 들어 있는 표라면 똑같이 앞자리 0을 잃을 위험이 있습니다. 엑셀 같은 스프레드시트 프로그램이 우편번호 열을 숫자 서식으로 자동 인식해 "0"을 지워버리는 것과 본질적으로 같은 종류의 사고입니다.
2. MODOO HUB 변환기는 실제로 어떻게 판단하는가
이 사이트의 CSV to JSON 변환기 소스코드를 직접 열어 확인한 결과, 값의 타입을 정하는 inferType() 함수는 다음 순서로 동작합니다. 먼저 값이 정확히 "true" 또는 "false"면 불리언으로 바꿉니다. 그 다음 빈 문자열이면 그대로 둡니다. 마지막으로 숫자 판정에는 Number()나 isNaN() 대신 다음 정규식을 씁니다.
/^-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?$/핵심은 정수 부분이 "0" 한 글자 단독이거나, 1~9로 시작해서 그 뒤에 숫자가 이어지는 형태만 허용한다는 점입니다. "007"은 "0" 뒤에 "07"이 더 남기 때문에 "0" 단독 조건에 맞지 않고, 그렇다고 1~9로 시작하지도 않으므로 정규식 전체가 매치되지 않습니다. 매치에 실패하면 함수는 원래 문자열을 그대로 반환합니다.
이 규칙 덕분에 "007", "0502", "010-1234-5678"처럼 앞자리가 0인 값은 전부 정규식 매치에서 탈락해 문자열로 남고, "0", "123", "3.14", "-7", "1e10"처럼 통상적인 숫자 표기만 실제 숫자 타입으로 변환됩니다. 즉 이 사이트의 변환기는 Number() 한 줄로 때우는 흔한 구현 방식과 달리, 앞자리 0 손실 버그를 애초에 정규식 설계로 차단해 둔 상태입니다.
| 입력 값 | 변환 결과 | 이유 |
|---|---|---|
| 007 | "007" (문자열 유지) | 0으로 시작하면서 뒤에 숫자가 더 있어 정규식 매치 실패 |
| 010-1234-5678 | "010-1234-5678" (문자열 유지) | 하이픈 포함으로 애초에 숫자 형식이 아님 |
| 05028 | "05028" (문자열 유지) | 0으로 시작하는 다자리 값 |
| 0 | 0 (숫자로 변환) | "0" 단독은 정당한 숫자 표기 |
| 123 | 123 (숫자로 변환) | 1~9로 시작하는 정상 숫자 |
3. 그래도 직접 확인해야 하는 이유
이 사이트의 변환기가 정규식으로 앞자리 0 문제를 막아두긴 했지만, 모든 CSV-JSON 변환 도구가 같은 방식으로 동작한다고 가정하면 안 됩니다. 엑셀에서 CSV로 내보내는 과정 자체에서 이미 "0502"가 "502"로 바뀌어 있을 수도 있고, 다른 온라인 변환기나 프로그래밍 언어의 라이브러리는 판정 기준이 다를 수 있습니다. 우편번호·전화번호·사번·계좌번호처럼 앞자리 0이 의미를 가지는 열이 있다면, 변환 후 출력된 JSON을 열어 그 값이 큰따옴표로 감싸인 문자열로 남아 있는지 눈으로 직접 확인하는 습관을 들이는 것이 가장 확실합니다.
4. 정리
- CSV는 타입이 없다: 모든 값이 그냥 텍스트이므로 변환기가 숫자 여부를 추측해야 합니다.
- 단순 Number() 판정은 위험: "007" → 7처럼 앞자리 0이 소리 없이 사라질 수 있습니다.
- 이 사이트 변환기는 정규식으로 방어: 0 단독이거나 1~9로 시작하는 값만 숫자로 바꾸고, 나머지는 문자열로 유지합니다.
- 중요한 열은 변환 후 눈으로 확인: 우편번호·전화번호·사번 열은 결과 JSON에서 따옴표가 남아 있는지 직접 확인하세요.
자주 묻는 질문
Q. CSV의 "007" 값이 JSON으로 변환하면 숫자 7이 되나요?
A. MODOO HUB의 CSV to JSON 변환기는 아닙니다. 이 변환기는 숫자로 인식하는 조건을 정규식 /^-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?$/ 로 제한해두었는데, 이 패턴은 "0" 단독이거나 1~9로 시작하는 숫자만 허용합니다. "007"은 0으로 시작하면서 뒤에 숫자가 더 있으므로 이 조건에 맞지 않아 정규식이 실패하고, 그 결과 원래 문자열 "007" 그대로 유지됩니다.
Q. 010-1234-5678 같은 전화번호도 숫자로 바뀔 위험이 있나요?
A. 없습니다. 하이픈이 포함된 값은 애초에 숫자 형식 정규식과 전혀 매치되지 않으므로 처음부터 문자열로 남습니다. 설령 하이픈이 없는 01012345678 같은 순수 숫자 나열이라도, 앞자리가 0이면 위 규칙에 의해 문자열로 유지되어 손실이 발생하지 않습니다.
Q. 이 변환기는 어떤 값을 실제로 숫자·불리언으로 바꾸나요?
A. "true"/"false" 문자열은 불리언으로, 그리고 0이거나 1~9로 시작하며 그 뒤에 숫자만 이어지는(선택적으로 소수점·지수 표기 포함) 값만 숫자로 변환됩니다. 예를 들어 "123", "0", "3.14", "-7"은 숫자가 되지만 "007", "010-1234", "1a2"처럼 순수한 숫자 형식이 아니거나 불필요한 앞자리 0이 있는 값은 전부 문자열로 남습니다.
Q. 모든 CSV-JSON 변환 도구가 이렇게 안전하게 동작하나요?
A. 아닙니다. 일부 스프레드시트 프로그램이나 간단한 변환기는 자바스크립트의 Number() 함수나 isNaN() 판정만으로 숫자 여부를 판단하는데, 이 방식은 "007"을 Number("007")=7로 그대로 변환해버려 앞자리 0을 잃어버립니다. 데이터를 변환기에 넣기 전에는 항상 앞자리 0이 있는 값이 결과에서 보존되는지 직접 확인하는 습관이 안전합니다.