Case Converter for Identifier Names — camelCase, snake_case, kebab-case and 4 More

Turn a name, or a whole column of names, into camelCase, PascalCase, snake_case, CONSTANT_CASE, kebab-case, Title Case and sentence case, and show which words it split the input into. Everything runs locally in your browser.

Worked names

You typeWords foundcamelCaseTitle Case
XMLHttpRequestxml · http · requestxmlHttpRequestXml Http Request
get_user_idget · user · idgetUserIdGet User Id
some-kebab-name.with.dotssome · kebab · name · with · dotssomeKebabNameWithDotsSome Kebab Name With Dots
iPhone 5S Casei · phone · 5 · s · caseiPhone5SCaseI Phone 5 S Case
How words are split, and the seven shapes

The same name, several spellings

Rewriting user_name into userName by hand is the kind of edit your eyes are worst at. There is no rule in your head for where a word ends inside XMLHttpRequest — is the H part of the acronym or the start of the next word? — so every pass is a coin flip, and a list of forty field names is forty coin flips. The splitting loop runs once, shows the words it found, and then all seven conventions render from that same list, so the styles cannot disagree with each other.

Reading the Words found cell is the whole workflow: if the words are right, all seven rows are right, and you can copy whichever column you need. If they are not, no style is going to rescue you.

How the input is split into words

Four rules, applied in this order. Everything below is what the script actually does, not what an ideal converter might do.

  1. Anything that is not a letter or a digit is a separator. Space, -, _, ., /, \, :, brackets, commas, and full-width CJK punctuation too. some-kebab-name.with.dots → some · kebab · name · with · dots. Consecutive separators collapse, and leading or trailing ones are ignored, so lots of spaces → lots · of · spaces.
  2. A capital after a lowercase letter or a digit opens a new word. getUserId → get · user · id, http2Server → http2 · server.
  3. A run of capitals is one acronym word — except its last letter. If the capital that ends the run is followed by a lowercase letter, it belongs to the next word instead. XMLHttpRequest → xml · http · request, parseHTTPResponse → parse · http · response, HTTPSConnection → https · connection. With no lowercase behind it the run stays whole: URL → url, MD5 → md5. Without this rule the capitals would swallow the word after them and HTTPSConnection would come out as one unbreakable lump.
  4. A digit run glues itself to the word in front of it; what follows depends on whether that word had letters. md5hash → md5 · hash and sha256sum → sha256 · sum, because the digits joined md / sha and then the lowercase started a new word. A number you lead with instead absorbs the letters after it: 2faLogin → 2fa · login, and 2024report stays one word.

Those lowercased words are then re-joined per style — camelCase, snake_case, kebab-case all lowercase; PascalCase and Title Case capitalise the first letter of every word; CONSTANT_CASE uppercases everything. Because the rejoin starts from lowercase, acronyms never stay all-caps: XMLHttpRequest becomes xmlHttpRequest, not XMLHTTPRequest. The Words found cell prints exactly that lowercased list, so it lines up character for character with the snake_case row.

Names that are not English: Chinese, Japanese and accented letters count as letters, so they join words and survive case mapping untouched — caféLatte → café · latte, CONSTANT_CASE gives CAFÉ_LATTE. But they carry no case, so they offer no boundary: 用户名abc is one single word, and 输出JSON字段 splits only where the ASCII J follows the CJK (输出 · json字段). Emoji and symbols are separators. On an engine old enough to fail the Unicode-property probe, the code falls back to code-point ranges where any character above 0x80 counts as a letter, so full-width punctuation and emoji can end up glued inside a word; every browser since roughly 2018 takes the Unicode path.

Feeding it a list

Tick Split the input by line and each line is tokenised on its own, producing one result line per name in all seven cells — you can copy a whole column at once. Blank lines are ignored, and a line with nothing but punctuation converts to nothing: it is skipped and its line number is named in the note, e.g. Heads up: line 3 had no words to split and was skipped. Since neither kind of line occupies a slot in the output, output row N is not necessarily input row N — that is why the Words found cell writes line 5: url · parser with the input line number attached. Use it to line the results up with what you pasted.

With the box unticked, the entire input including its line breaks is treated as one name, because a line break is just another separator: paste get_user_id and Some-Other NAME and you get getUserIdSomeOtherName out of it. That is the mode for turning a phrase like the user id column into an identifier.

Results you should not ship straight away

  • Acronyms your team wants uppercase. getURLPath here gives getUrlPath. If the ESLint config or house style demands getURL, edit the tail yourself — there is deliberately no acronym dictionary here.
  • Names where digits are meaning-bearing. v2rayClient splits as v2 · ray · client (v2RayClient), and VERSION_1_2 becomes version12 in camelCase because a case style has nowhere to put the separators between numbers. Check anything with a version, a size or a port in it.
  • Proper nouns and brands. MacDonald → macDonald, iPhoneCases → i · phone · cases. Whether Mac is a word of its own is a human convention, not something a scan of capitals can know.
  • Title Case is not headline style. Every word gets an initial capital, including a, of, to, the; sentence case just capitalises the first word. Real editorial caps rules need an editor.
  • Case mapping is generic, not locale-aware. Turkish İ lowercases to i plus a combining dot — two code points, visible in the output — and a lowercase i never comes back as İ. German ß and ẞ do map correctly (SS and ß), because the platform’s full case mapping covers them. What nothing covers is the Turkish/Azeri i pair, so check non-English proper nouns by eye.
  • Non-Latin scripts generally. The conversion only inserts separators; it will happily hand back Chinese characters you cannot use as an identifier in most languages.
  • Length. 4000 characters is the ceiling, and pasting several hundred short names is well inside it but makes each cell very tall; process a few dozen lines at a time if you plan to read them.

Questions

Why is XMLHttpRequest not XMLHTTPRequest in camelCase? Because the pipeline is “split into words, lowercase them, re-join per style”, and only PascalCase / Title Case put a capital back on a word’s first letter. Predictable beats clever here: a converter that guessed which fragments are acronyms would be wrong about as often as it was right.

aPIKey and APIKey give different answers — which is right? Both are produced faithfully: aPIKey reads as a · pi · key (aPiKey), APIKey as api · key (apiKey). The split depends on the capitals already in the input, so fix the source casing first if it is itself a typo.

Where does my input go? Into the splitting loop and nowhere else. It lives in the script, there is no eval, and the field names you paste are never put in front of a server, so they stay on this device.

Why does !!! show an error instead of seven empty rows? Printing empty strings suggests “converted, result blank”. Instead the outputs are cleared and the note says Nothing to split out of that — check the input, which is the honest answer.

Support on PayPal