대소문자 변환
프로그래밍 표기
- camelCase
- PascalCase
- snake_case
- CONSTANT_CASE
- kebab-case
- dot.case
- Train-Case
문장 표기
- UPPERCASE
- lowercase
- Title Case
- Sentence case
- iNVERSE cASE
입력한 내용은 저장, 기록, 공유되지 않습니다.
텍스트를 붙여넣으면 카멜케이스와 스네이크케이스부터 타이틀 케이스와 문장 케이스까지 모든 형식을 한 번에 보여줍니다. 모든 처리는 브라우저에서 이루어집니다.
사용 방법
- 텍스트나 식별자를 붙여넣습니다.
- 프로그래밍용과 문장용으로 나뉘어 모든 형식이 한 번에 생성됩니다.
- 필요한 형식을 복사합니다.
각 표기법과 어울리는 곳
camelCase는 소문자로 시작하고 이어지는 단어의 첫 글자를 대문자로 씁니다. JavaScript, Java, Swift에서 변수와 함수의 관례입니다. PascalCase는 첫 단어도 대문자로 시작하며 보통 타입, 클래스, 컴포넌트에 씁니다. snake_case는 소문자 단어를 밑줄로 잇고 Python, Ruby, Rust, SQL 식별자의 표준입니다. SCREAMING_SNAKE_CASE는 이를 대문자로 쓴 것으로 거의 상수와 환경 변수에만 씁니다.
kebab-case는 소문자 단어를 하이픈으로 잇는 방식으로, 밑줄이 불편하거나 잘 안 보이는 곳에 어울립니다. URL 슬러그, CSS 클래스 이름과 사용자 정의 속성, HTML 속성, 명령줄 플래그, npm 패키지 이름 같은 곳입니다. dot.case는 설정 키와 네임스페이스가 붙은 설정에서 볼 수 있습니다.
어떤 것을 고를지는 취향의 문제인 경우가 드뭅니다. 생태계마다 관례가 있고 린터가 이를 강제하며, 표기법이 맞지 않는 식별자는 그 파일 안에서 이질적으로 읽힙니다.
어려운 것은 단어 나누기
단어가 어디서 나뉘는지만 알면 표기법 변환은 쉽고, 단순한 구현이 넘어지는 곳은 바로 단어를 찾는 부분입니다. 입력은 밑줄, 하이픈, 점, 공백으로 나뉘고 대소문자 경계로도 나뉘므로, userName과 user_name을 파싱하면 같은 두 단어가 나옵니다.
연속된 대문자는 글자마다 한 단어가 아니라 하나의 단어로 취급합니다. XMLHttpRequest는 XML, Http, Request로 나뉘어 x_m_l_http_request가 아니라 xml_http_request가 되고, getUserID의 ID도 그대로 유지됩니다. 규칙은 연속된 대문자 뒤에 소문자가 오면 그 한 글자 앞에서 끝난다는 것이며, 이 덕분에 Http의 H가 앞 단어의 끝이 아니라 새 단어의 시작이 됩니다.
숫자는 앞 단어에 붙으므로 parseInt32는 parse와 Int32로 나뉩니다. 앞뒤의 구분자는 제거되고, 반복되는 구분자는 하나로 합쳐집니다.
문장용 표기법과 한중일 문자
Title Case는 모든 단어의 첫 글자를 대문자로 쓰는 것이 아닙니다. 영어 스타일 가이드는 관사, 짧은 전치사, 등위 접속사를 제목의 처음이나 끝에 오지 않는 한 소문자로 둡니다. 그래서 The Lord Of The Rings가 아니라 The Lord of the Rings가 됩니다. 기준선을 어디에 긋는지는 가이드마다 다르고 특히 네 글자 이상의 전치사에서 의견이 갈리므로, 중요하다면 사용하는 가이드를 확인하세요. Sentence case는 첫 단어만 대문자로 쓰고 나머지는 그대로 두는 방식으로, 제목 표기 규칙으로 점점 더 많이 쓰이고 있습니다.
한국어, 일본어, 중국어에는 대소문자 구분이 전혀 없으므로 이 문자들은 그대로 통과합니다. 섞여 있는 텍스트에서는 라틴 문자 부분만 변환됩니다. 한중일 문자가 이어진 부분은 하나의 단어로 취급합니다. 단어로 나누려면 사전과 형태소 분석기가 필요하고, 경계를 짐작하면 자신만만하게 틀린 결과가 나오기 때문입니다.
왕복 변환은 정보를 잃는다
식별자를 다른 표기법으로 바꿨다가 되돌린다고 항상 처음 모습이 나오지는 않습니다. snake_case를 camelCase로 바꿨다가 되돌리는 것은 안전합니다. 밑줄 경계가 대소문자 경계로 남기 때문입니다. 하지만 약어가 들어간 것은 그렇지 않습니다. HTTPServer는 http_server가 되고, 이를 되돌리면 HttpServer가 됩니다. HTTP가 약어였다는 정보는 대문자 표기에만 있었고, 소문자로 바꾸는 순간 사라졌습니다.
코드베이스 전체에서 이름을 바꿀 때 이 점이 중요하며, 변환을 연달아 이어 가지 말고 원래 이름에서 한 번만 변환해야 하는 이유이기도 합니다.
표기 관례가 갈린 이유
이 스타일 가운데 다른 것보다 나은 것은 없습니다. 모두 역사의 우연이 굳어져 커뮤니티 표준이 된 것입니다. C와 유닉스에서 그 뒤를 이은 문화가 소문자와 밑줄을 선호한 것은 초기 링커가 대소문자를 구분하지 않았고 긴 이름에 비용이 들었기 때문입니다. camelCase는 Smalltalk가 퍼뜨렸고 Java가 물려받았으며, JavaScript가 Java를 가깝게 따라가면서 다시 물려받았습니다.
Python의 스타일 가이드는 함수와 변수에 snake_case를, 클래스에 PascalCase를 명문화했고, 그 문서의 영향력이야말로 Python 코드가 프로젝트를 넘나들며 일관되게 보이는 이유입니다. 더 오래된 언어들은 해내지 못한 일이죠. CSS와 HTML이 kebab-case에 정착한 것은 문법이 대소문자를 구분하지 않기 때문이기도 하고, 식별자가 없는 언어에서는 하이픈이 자연스럽게 읽히기 때문이기도 합니다.
실무적 결론은, 올바른 표기는 주변 생태계가 쓰는 표기라는 것입니다. camelCase로 가득한 Python 파일이 읽기 어려운 이유는 그 스타일이 나빠서가 아니라, 프로젝트의 다른 모든 파일이 따르는 패턴을 깨뜨리기 때문입니다.
두 관례가 만나는 경계 넘기
실제 시스템에는 대개 관례가 바뀌는 이음매가 최소 하나 있습니다. PostgreSQL 스키마는 따옴표 없는 식별자가 소문자로 접히기 때문에 snake_case를 쓰고, 그 앞의 JSON API는 보통 camelCase를 쓰며, 그 JSON을 소비하는 React 컴포넌트는 컴포넌트에 PascalCase, props에 camelCase를 쓰고, 렌더링되는 CSS 클래스는 kebab-case입니다.
이음매에서 한 곳에서만 변환하는 것이 이 모든 것을 감당할 만하게 만드는 요령입니다. ORM과 직렬화 라이브러리는 거의 모두 바로 이 목적을 위한 명명 전략 설정을 제공하며, 필드를 하나씩 손으로 매핑하는 것보다 훨씬 낫습니다. 손 매핑은 오타와 조용히 사라지는 속성의 출처입니다.
피해야 할 것은 두 번 변환하는 것, 그리고 층마다 반대 방향으로 변환하는 것입니다. 필드가 user_name으로 도착해 클라이언트에서 userName이 되고, user_name을 기대하는 API에 userName으로 되돌아가면, 그 불일치는 보통 오류가 아니라 값이 조용히 무시되는 형태로 드러납니다.
코드베이스 전체 이름을 깨뜨리지 않고 바꾸기
이름 변경이 단순한 찾아 바꾸기로 끝나는 것은 가장 단순한 경우뿐입니다. 같은 식별자가 변수로, 직렬화에 쓰이는 문자열로, 데이터베이스 열로, URL 경로로, 문서 안에 나타날 수 있고 그것들은 같은 변경이 아닙니다. 변수 이름을 바꾸는 것은 안전하지만, 직렬화되는 키를 바꾸는 것은 API를 깨는 변경입니다.
통하는 순서는 변환을 이어 붙이지 말고 원래 이름에서 한 번만 변환하는 것입니다. 약어는 왕복을 버티지 못하기 때문입니다. HTTPServer는 http_server가 되고 되돌리면 HttpServer가 됩니다. 매핑 전체를 먼저 만들고, 검토한 다음 적용하세요.
오래가는 해결책은 린터입니다. ESLint, Ruff, golint 같은 도구는 새 코드에 명명 규칙을 강제할 수 있어, 큰 이름 변경을 한 번 끝낸 뒤 같은 문제가 되풀이되는 것을 막아 줍니다.
모든 언어에서 대소문자가 단순하지는 않다
대문자화와 소문자화는 로캘에 의존하는 연산이며, 잘 알려진 사례 몇 가지가 순진한 코드를 깨뜨립니다. 터키어에서 i의 대문자는 점이 있고 I를 소문자로 만들면 점 없는 문자가 됩니다. 그래서 터키어 로캘에서 대소문자를 무시한 비교를 하면 영어로는 똑같아 보이는 식별자가 일치하지 않을 수 있습니다. 흔한 방어책은 텍스트가 산문이 아니라 식별자일 때 로캘 불변 방식으로 소문자화하는 것입니다.
독일어 ß는 대문자로 SS가 되므로 연산이 문자열의 길이를 바꾸고, 왕복해도 원래 값이 돌아오지 않습니다. 그리스어 시그마는 단어 끝인지에 따라 소문자 형태가 둘입니다. 이 가운데 어느 것도 ASCII 식별자에는 영향을 주지 않으며 대부분의 코드가 그렇습니다. 하지만 사용자가 입력한 텍스트에는 모두 영향을 줍니다.
여기서의 변환은 라틴 문자에 작용하며, 일본어와 중국어와 한국어 문자는 그대로 둡니다. 이 문자 체계들에는 대소문자 구분이 아예 없기 때문입니다.
코드보다 오래 남는 것은 이름이다
표기 변환은 기계적인 일이지만 단어를 고르는 일은 그렇지 않고, 독자가 실제로 애를 먹는 것은 단어입니다. 일관된 스타일은 코드베이스를 한눈에 읽히게 하지만, 일관되게 적용된 나쁜 이름은 여전히 나쁜 이름입니다. 이름 바꾸기는 지금은 싸고, 그 식별자가 API와 데이터베이스 열과 대시보드 세 개에 퍼진 뒤에는 비쌉니다.
몇 가지 관례는 값을 합니다. 불리언은 질문을 분명하게 만드는 접두사가 붙을 때 가장 잘 읽힙니다. isActive, hasPermission, canEdit처럼요. 그냥 active는 상태인지 동작인지 모호합니다. 컬렉션은 복수형, 개별 항목은 단수형으로 써서 userList가 아니라 users와 user로 합니다. 단위는 이름에 넣습니다. timeoutMs, sizeBytes, priceCents처럼요.
알아볼 수 없을 만큼 줄이지는 마세요. usrMgr에서 아낀 두 글자는 앞으로의 모든 독자에게서 한순간씩을 가져가고, 코드베이스의 절반이 user, 나머지 절반이 usr를 쓰면 검색이 믿을 수 없게 됩니다. 동의어를 뒤섞는 것도 마찬가지입니다. fetch, get, load, retrieve가 네 모듈에서 같은 일을 하는 것은 영원히 내는 작은 세금이고, 하나로 정하는 것은 공짜입니다.
자주 묻는 질문
- 식별자에서 단어는 어떻게 구분되나요?
- 구분자와 대소문자 경계로 나누되 약어는 하나로 유지합니다. XMLHttpRequest는 x_m_l_http_request가 아니라 xml_http_request가 되고, getUserID의 ID도 I와 D로 쪼개지지 않습니다.
- 타이틀 케이스는 왜 모든 단어를 대문자로 하지 않나요?
- 스타일 가이드는 짧은 연결어를 맨 앞이나 맨 뒤가 아닌 한 소문자로 둡니다. 그래서 "the lord of the rings"는 "The Lord Of The Rings"가 아니라 "The Lord of the Rings"가 됩니다. 가이드마다 목록이 다르므로 세부 사항은 사용하는 가이드를 확인하세요.
- 한국어, 일본어, 중국어는 어떻게 처리되나요?
- 이 문자들은 대소문자 구분이 없으므로 그대로 유지됩니다. 혼합된 텍스트에서는 라틴 문자 부분만 변환되며, 사전 없이는 나눌 수 없으므로 연속된 CJK 문자는 하나의 단어로 취급합니다.
- 이름 목록을 한 번에 변환할 수 있나요?
- 네. 프로그래밍 표기는 줄 단위로 적용되므로 식별자 목록이 한 줄씩 변환됩니다. 문장 표기는 전체 텍스트에 적용되며 줄바꿈은 그대로 유지됩니다.
- 텍스트가 어딘가로 업로드되나요?
- 아닙니다. 변환은 브라우저에서만 실행되므로 데이터가 기기를 벗어나지 않습니다.
마지막 업데이트:
진행 단계, 예상 결과, 실제 결과를 적어 주세요. 비밀 정보와 개인 정보는 삭제해 주세요.
