CSV, 가장 간단하면서도 복잡한 데이터 형식
CSV(Comma Separated Values)는 쉼표로 구분된 값들의 형식입니다. 엑셀, Google Sheets, 데이터베이스 등 거의 모든 곳에서 데이터를 주고받을 때 사용됩니다.
하지만 표준이 명확하지 않아서 여러 변종이 있고, 인코딩, 줄바꿈, 따옴표 처리 등으로 인한 문제가 자주 발생합니다.
1부: CSV 기초
CSV의 기본 형식
이름,나이,직업
John,30,개발자
Jane,28,디자이너
Bob,35,매니저CSV 특징
- 텍스트 기반 (모든 프로그램에서 열 수 있음)
- 행(Row) 기반 구조
- 각 행은 새로운 레코드
- 각 값은 쉼표로 구분
2부: CSV 문법 규칙
1. 기본 규칙
필드1,필드2,필드3
값1,값2,값3
값4,값5,값62. 따옴표 처리
// 필드에 쉼표가 포함되면 따옴표로 감싸기
이름,주소,직업
John,"Seoul, South Korea",개발자
Jane,"New York, USA",디자이너3. 따옴표 내 따옴표
// 따옴표 안에 따옴표가 있으면 따옴표 2개로 표현
이름,설명
John,"그는 "좋은" 개발자다"
Jane,"그녀의 별명은 "JD""4. 줄바꿈
// 필드 내 줄바꿈 (따옴표로 감싸야 함)
이름,소개
John,"안녕하세요.
저는 개발자입니다."
Jane,"디자인을 합니다.
창의적인 작업을 좋아합니다."5. 빈 필드
이름,나이,직업
John,30,
Jane,,디자이너
,35,3부: CSV 파싱
JavaScript에서 CSV 파싱
간단한 방법 (정규표현식)
const csv = "이름,나이,직업
John,30,개발자
Jane,28,디자이너";
const rows = csv.trim().split('
');
const headers = rows[0].split(',');
const data = rows.slice(1).map(row => {
const values = row.split(',');
const obj = {};
headers.forEach((header, i) => {
obj[header] = values[i];
});
return obj;
});
console.log(data);
// [
// { 이름: 'John', 나이: '30', 직업: '개발자' },
// { 이름: 'Jane', 나이: '28', 직업: '디자이너' }
// ]올바른 방법 (라이브러리)
// npm install papaparse
import Papa from 'papaparse';
const csv = "이름,나이,직업
John,30,개발자
Jane,28,디자이너";
Papa.parse(csv, {
header: true,
complete: (results) => {
console.log(results.data);
}
});Python에서 CSV 파싱
CSV 모듈
import csv
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(row)
# {'이름': 'John', '나이': '30', '직업': '개발자'}Pandas
import pandas as pd
df = pd.read_csv('data.csv', encoding='utf-8')
print(df)
# 이름 나이 직업
# 0 John 30 개발자
# 1 Jane 28 디자이너4부: CSV 생성
JavaScript
const data = [
{ 이름: 'John', 나이: 30, 직업: '개발자' },
{ 이름: 'Jane', 나이: 28, 직업: '디자이너' }
];
// CSV 문자열 생성
const headers = Object.keys(data[0]);
const csv = [
headers.join(','),
...data.map(row =>
headers.map(header => {
const value = row[header];
// 쉼표나 따옴표가 있으면 따옴표로 감싸기
if (value.toString().includes(',') || value.toString().includes('"')) {
return '"' + value.toString().replace(/"/g, '""') + '"';
}
return value;
}).join(',')
)
].join('
');
console.log(csv);Python
import csv
data = [
{'이름': 'John', '나이': 30, '직업': '개발자'},
{'이름': 'Jane', '나이': 28, '직업': '디자이너'}
]
with open('output.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.DictWriter(f, fieldnames=['이름', '나이', '직업'])
writer.writeheader()
writer.writerows(data)5부: 인코딩 처리
일반적인 인코딩
UTF-8
- 표준 (권장)
- 한글, 특수문자 완벽 지원
EUC-KR
- 구형 시스템
- 한글 전용
CP949
- Windows 한글 인코딩잘못된 인코딩 감지
❌ 이상한 글자: "???엗엗" (인코딩 오류)
원인: UTF-8 파일을 EUC-KR로 읽음
해결:
1. 원본 인코딩 확인
2. 올바른 인코딩으로 변환Python에서 인코딩 처리
import chardet
# 파일의 인코딩 자동 감지
with open('file.csv', 'rb') as f:
raw_data = f.read()
result = chardet.detect(raw_data)
encoding = result['encoding'] # 'UTF-8', 'EUC-KR' 등
# 올바른 인코딩으로 읽기
df = pd.read_csv('file.csv', encoding=encoding)6부: CSV의 문제점과 해결
문제 1: 따옴표 처리
❌ 잘못된 방법:
"John "Developer" Lee" (내부 따옴표 처리 안 함)
✅ 올바른 방법:
"John ""Developer"" Lee" (따옴표를 2개로)문제 2: 줄바꿈
❌ 잘못된 파싱:
각 줄바꿈을 새로운 레코드로 인식
✅ 올바른 처리:
따옴표로 감싼 필드 내의 줄바꿈 보존문제 3: BOM(Byte Order Mark)
일부 Windows 프로그램이 UTF-8 BOM으로 저장
→ 첫 글자가 이상해짐 (예: 이름 → "이름)
해결: BOM 제거하기 (라이브러리 사용)문제 4: 행 끝 문자 (CRLF vs LF)
Windows: CRLF (
)
Mac/Linux: LF (
)
CSV 읽을 때 이를 정규화해야 함7부: CSV vs JSON
CSV:
장점: 간단, 작음, 엑셀 호환
단점: 계층 구조 불가, 타입 정보 없음
JSON:
장점: 계층 구조, 타입 정보
단점: 파일 크기 크다, 엑셀 읽기 어려움
선택:
- 엑셀 사용자와 협업: CSV
- API 응답: JSON
- 정형 데이터: CSV
- 복잡한 구조: JSON자주 하는 실수
1. 간단한 split() 사용
❌ row.split(',') (따옴표 처리 안 됨)
✅ CSV 파싱 라이브러리 사용
2. 인코딩 무시
❌ 인코딩 지정 안 함
✅ UTF-8로 통일하거나 명시적 지정
3. 따옴표 이스케이핑 무시
❌ 특수문자 포함할 때 따옴표 안 함
✅ 항상 따옴표로 감싸기
마무리
CSV는 간단해 보이지만, 제대로 처리하려면 신경 써야 할 부분이 많습니다. CSV 라이브러리를 사용하고, 인코딩을 명시적으로 지정하면 대부분의 문제를 해결할 수 있습니다.