JavaScript / 숫자에 천 단위 쉼표 추가하는 방법, 제거하는 방법
숫자에 천 단위 쉼표를 표시하려면 toLocaleString("ko-KR") 또는 Intl.NumberFormat("ko-KR")을 사용합니다. 쉼표가 있는 문자열을 계산하려면 먼저 입력 형식과 쉼표 위치를 검사한 뒤 쉼표를 제거하고 숫자로 변환하세요. 표시 문자열과 계산용 숫자는 별도로 관리하는 것이 좋습니다.
로케일을 지정해 쉼표로 표시하기
(123456789).toLocaleString("ko-KR"); // "123,456,789"
(123456789).toLocaleString("de-DE"); // "123.456.789"
const formatter = new Intl.NumberFormat("ko-KR");
formatter.format(123456789); // "123,456,789"
로케일(locale)은 언어·지역별 표시 규칙을 지정하는 값입니다. 생략하면 실행 환경의 기본 로케일을 사용하므로 구분 기호가 항상 쉼표라고 가정하면 안 됩니다. 같은 옵션으로 여러 값을 표시한다면 Intl.NumberFormat 객체를 만들어 재사용할 수 있습니다. 반환값은 계산용 숫자가 아니라 문자열입니다. toLocaleString()의 로케일 지정과 Intl.NumberFormat 안내를 참고하세요.
소수 자릿수와 통화 옵션
const decimal = new Intl.NumberFormat("ko-KR", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
decimal.format(1234.5); // "1,234.50"
const won = new Intl.NumberFormat("ko-KR", {
style: "currency",
currency: "KRW"
});
won.format(123456789); // 원화 기호와 천 단위 구분으로 표시
최소·최대 소수 자릿수를 함께 지정하면 표시 길이와 반올림 범위를 분명히 할 수 있습니다. 일반 숫자 표시의 기본 최대 소수 자릿수는 3이므로, 더 많은 소수를 보이려면 옵션을 지정하세요. 통화 스타일은 통화별 기본 소수 자릿수를 적용합니다. 표시 과정의 반올림은 원래 변수에 저장한 숫자를 변경하지 않습니다. 옵션별 차이는 NumberFormat 생성자 옵션에서 확인할 수 있습니다.
쉼표 제거와 숫자 변환은 별도 작업입니다
const text = "123,456,789"; const plain = text.replace(/,/g, ""); plain; // "123456789" typeof plain; // "string" Number(plain); // 123456789
/,/g는 쉼표를 모두 찾는 정규표현식입니다. 정규표현식은 문자열의 패턴을 검사하거나 치환하는 표기이며, g는 첫 일치에서 멈추지 않고 전체를 대상으로 한다는 뜻입니다. replace()는 새 문자열을 반환하므로 원래 문자열 자체를 숫자로 바꾸지 않습니다.
이 단순 치환만으로는 입력이 올바른지 알 수 없습니다. "12,34"는 잘못된 묶음인데 쉼표를 제거하면 1234가 되어 오류가 숨겨집니다. 숫자 외의 모든 문자를 제거하는 방식은 -12.5를 125로 바꾸는 등 값을 훼손할 수 있으므로 피하세요.
전체 예제: 입력 형식부터 검사하기
아래 코드를 UTF-8의 number-grouping.html로 저장해 브라우저로 여세요. 이 예제는 앞뒤 공백, 선택적인 부호, 정수부와 선택적인 소수부를 허용합니다. 쉼표가 있으면 첫 묶음은 1~3자리, 뒤의 묶음은 정확히 3자리여야 합니다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>천 단위 쉼표와 입력 검사</title>
<style>
body { margin: 24px; font: 16px/1.7 sans-serif; }
input, button, select { font: inherit; max-width: 100%; }
label { display: block; margin-top: 12px; }
#output { white-space: pre-wrap; overflow-wrap: anywhere; }
</style>
</head>
<body>
<label for="value">쉼표가 있거나 없는 십진수</label>
<input id="value" type="text" value="1,234,567.89">
<button id="format" type="button">검사하고 표시</button>
<pre id="output" aria-live="polite"></pre>
<script>
function parseGroupedDecimal(input) {
const text = input.trim();
const pattern = /^[+-]?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/;
if (!pattern.test(text)) return null;
const value = Number(text.replace(/,/g, ""));
return Number.isFinite(value) ? value : null;
}
const formatter = new Intl.NumberFormat("ko-KR", {
useGrouping: true,
maximumFractionDigits: 20
});
function show() {
const input = document.getElementById("value").value;
const value = parseGroupedDecimal(input);
const output = document.getElementById("output");
if (value === null) {
output.textContent = "쉼표 위치와 숫자 형식을 확인하세요.";
return;
}
output.textContent = `숫자: ${value}\n표시: ${formatter.format(value)}\n자료형: ${typeof value}`;
}
document.getElementById("format").addEventListener("click", show);
show();
</script>
</body>
</html>
초기 입력은 숫자 1234567.89로 변환되고 1,234,567.89로 표시됩니다. -12,345.6과 0은 허용하지만 12,34, 1,234,, ₩1,000, 빈 값은 거부합니다. 실패를 null로 반환하므로 유효한 숫자 0과 구분할 수 있습니다. 최대 소수 자릿수 20은 표시 옵션일 뿐, Number의 실제 정밀도를 늘리지 않습니다.
정규표현식으로 표시 문자열을 직접 만들 때
const text = "-1234567.8900";
const [integer, fraction] = text.split(".");
const grouped = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
const result = fraction === undefined
? grouped
: `${grouped}.${fraction}`;
console.log(result); // -1,234,567.8900
이 방식은 이미 형식을 검사한 십진 문자열의 정수부에만 쉼표를 넣습니다. 소수부를 분리하지 않고 전체 문자열에 숫자 묶음 패턴을 적용하면 소수부에도 쉼표가 생길 수 있습니다. 기존 소수부의 끝 0을 그대로 보관할 필요가 있을 때는 문자열 처리가 유용하지만, 지수 표기나 다른 지역 형식까지 자동 처리하는 범용 숫자 포맷터는 아닙니다.
다른 지역 형식과 큰 정수의 한계
- 독일어 표기의
"1.234,56"는 이 예제의 입력 형식이 아닙니다.Intl.NumberFormat은 표시 기능이며 역변환용 범용 파서가 아니므로, 입력에 허용할 지역 규칙을 먼저 정하세요. - Number의 안전한 정수 범위를 넘으면 자릿수가 손실될 수 있습니다. 큰 정수는 문자열을 보관한 뒤 허용한 정수 형식에 한해
BigInt로 처리할 수 있지만, BigInt는 소수를 저장하지 않습니다. - 입력값의 유한성·자료형 검사는 Number() 변환과 검사를, 계산 결과의 자릿수 처리는 내림·올림·반올림의 차이를 참고하세요.

