Case converter
Convert identifiers and text to camelCase, PascalCase, snake_case, SCREAMING_SNAKE_CASE, kebab-case, Train-Case, dot.case, path/case and four more at once, one line at a time, with acronyms and digits split the way style guides expect.
Split intouserProfileImageURL
- camelCaseJavaScript, Java and Swift variables, functions and object keys.
- userProfileImageUrl
- PascalCaseType names nearly everywhere; every public C# and .NET member.
- UserProfileImageUrl
- snake_casePython and Rust functions and variables; SQL columns.
- user_profile_image_url
- SCREAMING_SNAKE_CASEConstants, and environment variable names.
- USER_PROFILE_IMAGE_URL
- kebab-caseURL slugs, CSS properties and custom properties, npm package names.
- user-profile-image-url
- Train-CaseHTTP header names, such as Content-Type and X-Request-Id.
- User-Profile-Image-Url
- dot.caseJava packages, config keys, metric and feature-flag names.
- user.profile.image.url
- path/caseFile paths, route segments and object storage keys.
- user/profile/image/url
- Title CaseHeadings, column headers and button labels.
- User Profile Image Url
- Sentence caseUI copy, log messages and commit message subjects.
- User profile image url
- lower caseThe words on their own, space separated.
- user profile image url
- UPPER CASEThe words on their own, capitals throughout.
- USER PROFILE IMAGE URL
Convert identifiers and text to camelCase, PascalCase, snake_case, SCREAMING_SNAKE_CASE, kebab-case, Train-Case, dot.case, path/case and four more at once, one line at a time, with acronyms and digits split the way style guides expect.
On this page
How to use this tool#
- Type or paste into the box. Every format below it updates as you type, so there is no direction to pick and no button to press. The example is there to be replaced.
- Take the one you want. Each row has its own copy button, labelled with the format name.
- Convert a whole list at once. Put one identifier per line and each line is converted on its own. Blank lines stay blank, so a pasted column of column names or environment variables comes back in the same shape.
- Check the split under the box. The tool shows the words it found before it rebuilt them. When a result looks wrong, that line is where it went wrong, and the usual fix is to put a separator where you meant one.
What a case converter actually does#
Converting between naming conventions is two steps. First split the text into words. Then join those words with a separator and a capitalisation rule. The second step is trivial; every interesting thing about a case converter happens in the first one, becauseparseHTTPResponse has no separators in it and you still have to find the three words inside.
That is why the same input can produce different output in different tools, and why this page shows you the split it used.
The conventions, and where each one is used#
| Convention | Example | Conventionally used for |
|---|---|---|
| camelCase | parseHttpResponse | JavaScript and Java variables, functions and object keys. Go unexported names. |
| PascalCase | ParseHttpResponse | Type names in most languages. Public C# and .NET members. Go exported names. |
| snake_case | parse_http_response | Python and Rust functions, variables and modules. Database column names. |
| SCREAMING_SNAKE_CASE | PARSE_HTTP_RESPONSE | Constants in Python, Rust, Java and C. Environment variable names. |
| kebab-case | parse-http-response | URL slugs, CSS properties and custom properties, npm package names, long CLI flags. |
| Train-Case | Parse-Http-Response | HTTP header names, such as Content-Type and X-Request-Id. |
| dot.case | parse.http.response | Java package names, config keys, metric and feature-flag names. |
| path/case | parse/http/response | File paths, route segments, object storage keys. |
| Title Case | Parse Http Response | Headings, table headers, button labels. |
| Sentence case | Parse http response | UI text, log messages, commit message subjects. |
The tool also offers plain lower case and UPPER CASE, which are the same word split written out with spaces and nothing else.
What the language guides actually say
- Python.PEP 8: "Function names should be lowercase, with words separated by underscores as necessary to improve readability", "Class names should normally use the CapWords convention", constants are "written in all capital letters with underscores separating words", and "Modules should have short, all-lowercase names."
- Rust. TheAPI guidelines put modules, functions, methods and local variables in
snake_case, types, traits and enum variants inUpperCamelCase, and statics and constants inSCREAMING_SNAKE_CASE. - C# and .NET. Thecapitalization conventions use PascalCase for namespaces, types and members, and camelCase for parameters.
- Go.Effective Go: "the convention in Go is to use MixedCaps or mixedCaps rather than underscores to write multiword names." Which of the two you use is not a style choice: a capital first letter is what exports an identifier from its package.
- Environment variables. POSIX (IEEE Std 1003.1, chapter 8) says the names used by standard utilities "consist solely of uppercase letters, digits, and the <underscore> ('_') ... and do not begin with a digit", and that "The name space of environment variable names containing lowercase letters is reserved for applications." So
SCREAMING_SNAKE_CASEfor anything the shell will see. - CSS. Property names and keywords are hyphenated, andCSS 2.1says "All CSS syntax is case-insensitive within the ASCII range". Custom properties are the exception: perMDN, "Custom property names are case sensitive", so
--my-colorand--My-colorare two different properties.
How this tool splits words#
Anything that is not a letter, a digit or a combining mark ends a word, so underscores, hyphens, dots, slashes and spaces all work as separators, and leading, trailing or repeated separators are ignored. Inside a run of letters and digits, three rules find the rest of the boundaries.
- Lowercase or digit followed by a capital starts a word. This is the plain camelCase rule:
userProfileis two words. - A run of capitals stays one word, except that its last capital starts the next word when a lowercase letter follows. That keeps acronyms whole:
parseHTTPResponsesplits into parse, HTTP, Response rather than parse, H, T, T, P, Response, andXMLHttpRequestsplits into XML, Http, Request. - Digits attach to the word in front of them.
utf8Decoderis utf8 and Decoder, not utf, 8, Decoder, soutf8_decoderandbase64Encodesurvive a round trip. A capital after the digits still starts a new word, which is what makesversion2Betacome out asversion2_beta.
parseHTTPResponse -> parse | HTTP | Response
XMLHttpRequest -> XML | Http | Request
userProfileImageURL -> user | Profile | Image | URL
utf8Decoder -> utf8 | Decoder
version2Beta -> version2 | Beta
HTML5Parser -> HTML5 | Parser
my-XMLParser_v2 -> my | XML | Parser | v2
éléphantRose -> éléphant | RoseThe rules are written with Unicode property escapes, not A-Z, soéléphantRose splits into éléphant and Rose and приветМир into привет and Мир. Scripts without letter case, such as Chinese, Japanese and Arabic, have no case boundaries to find, so a run of them stays one word and the conventions that only change case leave the text alone.
Acronyms: where the style guides disagree#
Splitting an acronym is the easy half. Deciding how to write it back is where the guides part company, and there is no answer that is right everywhere.
- Google Java Style lowercases them.Section 5.3 says to "lowercase everything (including acronyms)", then uppercase the first character of each word. Its own table gives
XmlHttpRequestas correct andXMLHTTPRequestas incorrect, andnewCustomerIdas correct againstnewCustomerID. - PEP 8 does the opposite for Python class names: "When using acronyms in CapWords, capitalize all the letters of the acronym. Thus
HTTPServerErroris better thanHttpServerError." - Go keeps the case consistent within the word. Thecode review comments say initialisms "have a consistent case. For example, 'URL' should appear as 'URL' or 'url' (as in 'urlPony', or 'URLPony'), never as 'Url'", which is why the method is
ServeHTTPand notServeHttp. - Rust sides with Google. The API guidelines: "in UpperCamelCase, acronyms and contractions of compound words count as one word: use
Uuidrather thanUUID,Usizerather thanUSizeorStdinrather thanStdIn." In snake_case they are simply lowercased. - .NET splits the difference by length. Acronyms of three letters or more are PascalCased like any word (
HtmlTag), but "A special case is made for two-letter acronyms in which both letters are capitalized", givingIOStream. In a camelCased name a leading two-letter acronym goes fully lowercase:ioStream.
This tool follows the Google and Rust rule: it lowercases the whole word and capitalises the first letter, so parseHTTPResponse becomes parseHttpResponse andXMLHttpRequest becomes XmlHttpRequest. That choice is what makes the conversions reversible, since it is the only one where converting a result again leaves it unchanged.
Things that catch people out#
Names with a capital in the middle of a word
IPv6, IPv4 and iOS break every rule-based splitter, because the capital run and the lowercase letter belong to the same word. This tool readsIPv6Address as I, Pv6, Address. So does everything else that works this way: Google Java Style sidesteps the problem by telling you to write supportsIpv6OnIos in the first place. If you have one of these, separate the words yourself and convertipv6_address rather than IPv6Address.
Converting throws information away
parseHTTPResponse to parse_http_response and back gives youparseHttpResponse, not what you started with. The capitals are not recoverable because nothing recorded that HTTP was an acronym. Convert in one direction, review the result, and do not chain conversions expecting the original back.
Case folding and the machine's locale
This tool uses JavaScript's toUpperCase and toLowerCase, which theECMAScript specification defines in terms of the Unicode Default Case Conversion, so they do not consult the locale. The locale-sensitive versions do:toLocaleUpperCase turns istanbul into İSTANBUL with a dotted capital I under a Turkish locale, and ISTANBUL anywhere else. If your own code uppercases identifiers with the locale-aware functions, a Turkish machine will not agree with your CI.
Separators that are part of the data
A dot or a slash in the input is read as a separator, always. If you pastesrc/main.ts you get three words, not a filename with an extension. Convert the parts you mean to convert.
Converting a case in code#
Worth writing yourself for a script, worth a library in an application. Both versions below use the same two-step approach as this page, without the acronym and digit refinements.
JavaScript
// Two steps: split into words, then join with a rule.
function words(text) {
return text
.replace(/([\p{Ll}\p{N}])(\p{Lu})/gu, '$1 $2') // fooBar -> foo Bar
.replace(/(\p{Lu}+)(\p{Lu}\p{Ll})/gu, '$1 $2') // HTTPFoo -> HTTP Foo
.split(/[^\p{L}\p{N}]+/u)
.filter(Boolean);
}
const cap = (w) => w[0].toUpperCase() + w.slice(1).toLowerCase();
const camel = (t) => words(t).map((w, i) => (i ? cap(w) : w.toLowerCase())).join('');
const snake = (t) => words(t).map((w) => w.toLowerCase()).join('_');
const kebab = (t) => words(t).map((w) => w.toLowerCase()).join('-');
camel('parse_http_response'); // 'parseHttpResponse'
snake('parseHTTPResponse'); // 'parse_http_response'
kebab('XMLHttpRequest'); // 'xml-http-request'
snake('utf8Decoder'); // 'utf8_decoder'Python
import re
def words(text):
text = re.sub(r'([a-z0-9])([A-Z])', r'\1 \2', text) # fooBar -> foo Bar
text = re.sub(r'([A-Z]+)([A-Z][a-z])', r'\1 \2', text) # HTTPFoo -> HTTP Foo
return [w for w in re.split(r'[^A-Za-z0-9]+', text) if w]
def snake(text):
return '_'.join(w.lower() for w in words(text))
def camel(text):
parts = words(text)
if not parts:
return ''
return parts[0].lower() + ''.join(w.capitalize() for w in parts[1:])
snake('parseHTTPResponse') # 'parse_http_response'
camel('parse_http_response') # 'parseHttpResponse'
snake('utf8Decoder') # 'utf8_decoder'
# The character classes are ASCII. Swap in \w with re.UNICODE, or the
# regex module's \p{Lu}, if your identifiers are not all Latin.Nothing here leaves your browser#
The splitting and the conversion run on your machine, in JavaScript, after the page has loaded. Nothing you type is sent anywhere, and there is nowhere to send it: this site is static files with no backend. Disconnect from the network and the tool keeps working, which is the quickest way to prove it. That matters when the identifiers you are renaming come from an unreleased schema.
Questions people ask#
How do I convert snake case to camel case?
Paste the snake_case name into the box and read the camelCase row.parse_http_response becomes parseHttpResponse. In code it is a one liner: split on _, capitalise every part after the first, join with nothing.
What is kebab case?
Lowercase words joined with hyphens: parse-http-response. It is the convention for URL slugs, CSS property and custom property names, npm package names and long command-line options. It is also called dash case, lisp case or spinal case. The name comes from the words looking like items on a skewer.
What is the difference between camelCase and PascalCase?
Only the first letter. Both join capitalised words with no separator; camelCase leaves the first word lowercase and PascalCase capitalises it. PascalCase is also called upper camel case, and camelCase lower camel case, which is what Google Java Style and the Rust guidelines call them.
Can it convert a whole list at once?
Yes. Put one identifier per line. Each line is split and rebuilt independently, so words never run together across a line break, and blank lines are kept. Carriage returns from Windows text are normalised to plain line feeds.
Why did my acronym come back as Http?
Because that is the rule this tool follows, the one from Google Java Style and the Rust API guidelines. It is also the only rule under which converting a result again leaves it unchanged. If your project follows PEP 8's CapWords rule or Go's initialism rule, fix the acronym by hand after converting.
Why Train-Case and not COBOL-CASE?
Because Train-Case is the name with a real source behind it: it is what the widely usedchange-case library ships and documents for capitalised words joined by hyphens. COBOL-CASE turns up only in blog posts, and usually means something else, all-capitals with hyphens. If that is what you want, take the SCREAMING_SNAKE_CASE row and replace the underscores.
Does it handle accents and non-Latin text?
Yes. The word splitting uses Unicode letter, digit and mark properties rather than an ASCII range, so accented Latin, Cyrillic and Greek split on their own case changes, and scripts without case pass through as single words.
Related tools
Percent-encode and decode URLs and query strings, with encodeURIComponent, encodeURI, strict RFC 3986 and form encoding, plus a breakdown of the query parameters.
Encode text or a file to Base64 and decode it back, with correct UTF-8, standard and URL-safe alphabets, optional padding, MIME line wrapping and data: URIs.
Convert YAML to JSON and JSON back to YAML in your browser, following YAML 1.2, with anchors and merge keys resolved, multi-document streams, and syntax errors reported by line and column.