The Challenge

I was reading Google's Java Style Guide the other day and stumbled over their algorithm to convert any arbitrary string into camelCase notation. In this challenge you have to implement this algorithm since you dont want to do all this stuff in your head when you are writing your super competitive Java submissions to code-golf challenges.

Note: I made some small adjustments to the algorithm. You need to use the one specified below.

The algorithm

You start with an arbitrary input string and apply the following operations to it:

  1. Remove all apostrophes `'
  2. Split the result into words by splitting at
    • characters that are not alphanumerical and not a digit [^a-zA-Z0-9]
    • Uppercase letters which are surrounded by lowercase letters on both sides. abcDefGhI jk for example yields abc Def Ghi jk
  3. Lowercase every word.
  4. Uppercase the first character of every but the first word.
  5. Join all words back together.

Additional notes

  • The input will only contain printable ASCII.
  • If a digit is the first letter in a word, leave it as it is and don't capalize something else in this word.
  • The input will always have at least one character.


Test cases

"Programming Puzzles & Code Golf" -> "programmingPuzzlesCodeGolf"
"XML HTTP request" -> "xmlHttpRequest"
"supports IPv6 on iOS?" -> "supportsIpv6OnIos"
"SomeThing w1th, apo'strophe's and' punc]tuation" -> "someThingW1thApostrophesAndPuncTuation"
"nothing special" -> "nothingSpecial"
"5pecial ca5e" -> "5pecialCa5e"
"1337" -> "1337"
"1337-spEAk" -> "1337Speak"
"whatA mess" -> "whataMess"
"abcD" -> "abcd"
"a" -> "a"
"B" -> "b"

Happy Coding!

  • 3
    \$\begingroup\$ Interesting, I never knew this was called "camelCase". Name is fitting I suppose... \$\endgroup\$ – Ashwin Gupta Mar 3 '16 at 4:53
  • 4
    \$\begingroup\$ There are more: snake_case & PascalCase \$\endgroup\$ – Martijn Mar 3 '16 at 8:50
  • 14
    \$\begingroup\$ @Martijn snake_case because of Python, of course. FORTH also has FORTHCASE and APL has unreadable in any case \$\endgroup\$ – cat Mar 3 '16 at 14:40
  • \$\begingroup\$ Test case 4 should have ApostropheS in the output. \$\endgroup\$ – Titus Nov 10 '16 at 16:45
  • \$\begingroup\$ @Titus No, it is correct. Apostrophes are removed before the input is splitted. \$\endgroup\$ – Denker Nov 10 '16 at 21:42

14 Answers 14


Retina, 56 bytes

Byte count assumes ISO 8859-1 encoding.


Try it online!


This implements the specification quite literally:


Remove apostrophes and backticks.


Split the string around non-word characters (in regex this also excludes digits and underscores), or underscores or positions that have a lower case letter on the left and and upper case, lower case on the right. This would create some empty segments when there are two non-letter, non-digit characters in a row, or more important at the beginning of the string. We get rid of those with the _ option. Here, "splitting" means put each remaining part on its own line.


Convert everything to lower case.


Convert each character that occurs after the linefeed to upper case. This will conveniently skip the first word because there's no linefeed in front of it.

Get rid of the linefeeds to join everything back together.

| improve this answer | |
  • \$\begingroup\$ You beat me to it. Nice one! \$\endgroup\$ – mbomb007 Mar 2 '16 at 20:01
  • \$\begingroup\$ This question may be a bit weird, but...should I post my answer if it's shorter than yours and also in Retina? I was working on it before your answer appeared, but then it did and now I don't know if I should post it. \$\endgroup\$ – daavko Mar 2 '16 at 20:11
  • 5
    \$\begingroup\$ @daavko Sure, post it (I usually decide based on how different the approach is to the existing answer... if it's the exact same thing with a byte shaved off somewhere I normally just comment on that answer, but if it's a lot shorter of a different approach, then I'd just post a separate answer). \$\endgroup\$ – Martin Ender Mar 2 '16 at 20:12
  • 2
    \$\begingroup\$ @daavko The lookaround is necessary though. Note that your answer doesn't retain the capitalisation of Thing although it should. \$\endgroup\$ – Martin Ender Mar 2 '16 at 20:19
  • 1
    \$\begingroup\$ @MartinBüttner Oh...I didn't notice that. Oh well, I'll successfully answer some other challenge, then. \$\endgroup\$ – daavko Mar 2 '16 at 20:22

Java, 198 190 bytes

+3 bytes because I forgot that \W+ == [^a-zA-Z0-9_]+ and I need to match [^a-zA-Z0-9]+

-11 bytes thanks to user20093 - ?: instead of if/else

Because, Java.

s->{String[]a=s.replaceAll("`|'","").split("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])");s="";for(String w:a){String t=w.toLowerCase();s+=a[0]==w?t:t.toUpperCase().charAt(0)+t.substring(1);}return s;}

This is a lambda. Call like so:

UnaryOperator<String> op = s->{String[]a=s.replaceAll("`|'","").split("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])");s="";for(String w:a){String t=w.toLowerCase();s+=a[0]==w?t:t.toUpperCase().charAt(0)+t.substring(1);}return s;};
System.out.println(op.apply("Programming Puzzles & Code Golf"));

Readable version:

public static String toCamelCase(String s) {
    String[] tokens = s
            .replaceAll("`|'", "") // 1. Remove all apostrophes
            .split("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])"); // 2. Split on [\W_]+ or between [a-z] and [A-Z][a-z]
    s = ""; // Reusing s for building output is cheap
    for (String token : tokens) {
        String lowercaseToken = token.toLowerCase(); // 3. Lowercase every word
        s += tokens[0].equals(token)?lowercaseToken:lowercaseToken.toUpperCase().charAt(0) + lowercaseToken.substring(1); // 4. Uppercase first char of all but first word
        // ^ 5. Join all words back together
    return s;
| improve this answer | |
  • 1
    \$\begingroup\$ It's not Swift... \$\endgroup\$ – CalculatorFeline Mar 3 '16 at 4:17
  • 2
    \$\begingroup\$ Welcome to Programming Puzzles & Code Golf! This is a nice first answer! \$\endgroup\$ – Alex A. Mar 3 '16 at 4:28
  • 1
    \$\begingroup\$ @CatsAreFluffy What? \$\endgroup\$ – cat Mar 3 '16 at 14:49
  • \$\begingroup\$ if you replace conditional statement(if/else) with conditional expression (?:) you could save around 9 bytes \$\endgroup\$ – user902383 Mar 4 '16 at 11:55
  • \$\begingroup\$ Don't know how I missed that @user902383 - added for -11 bytes. Unfortunately I had to add 3 as well to match _ as a token delimiter. \$\endgroup\$ – CAD97 Mar 4 '16 at 19:12

JavaScript (ES6), 156 154 152 148 145 141 140 bytes

Thanks @Neil (6 bytes), @ETHproductions (3 bytes), and @edc65 (7 bytes)

a=>a[r='replace'](/`|'/g,a='')[r](/[a-z](?=[A-Z][a-z])/g,'$& ')[r](/[^\W_]+/g,b=>a+=(a?b[0].toUpperCase():'')+b.slice(!!a).toLowerCase())&&a

Removes apostrophes, then does a replace to split on special characters/before surrounded capitals, then combines with proper casing. Unfortunately, toLowerCase() and toUpperCase() are annoyingly long and hard to avoid here...

| improve this answer | |
  • 1
    \$\begingroup\$ I was working on a different approach which your b.slice(i>0) approach blows out of the water, but in the mean time my match regex of /[A-Z]?([a-z0-9]|[0-9A-Z]{2,})+([A-Z](?![a-z]))?/g does appear to save 2 bytes over your otherwise ingenious replace approach. \$\endgroup\$ – Neil Mar 2 '16 at 20:28
  • 1
    \$\begingroup\$ Or I could just save 2 bytes on your replace directly: replace(/[a-z](?=[A-Z][a-z])/g,'$& ') \$\endgroup\$ – Neil Mar 2 '16 at 20:30
  • 1
    \$\begingroup\$ Usually match...map can be replaced with replace \$\endgroup\$ – edc65 Mar 2 '16 at 21:45
  • 1
    \$\begingroup\$ @edc65 I get a minimum of 160 bytes with that approach: a=>a.replace(/`|'/g,'').replace(/[a-z](?=[A-Z][a-z])/g,'$& ').replace(/[\W_]*([a-z0-9]+)[\W_]*/gi,(_,b,i)=>(i?b[0].toUpperCase():'')+b.slice(i>0).toLowerCase()) \$\endgroup\$ – ETHproductions Mar 2 '16 at 21:50
  • 2
    \$\begingroup\$ On the other hand, I would like to offer b=>a+=(a?b[0].toUpperCase():'')+b.slice(!!a).toLowerCase() which I believe saves you another 4 bytes. \$\endgroup\$ – Neil Mar 3 '16 at 0:28

vim, 69 68 66


vim shorter than Perl?! What is this madness?

:s/[`']//g<cr>           remove ` and '
:s/                      match...
 [a-z]\zs\ze[A-Z][a-z]   right before a lowercase-surrounded uppercase letter
 \|\W\|_                 or a non-word char or underscore
 /\r/g<cr>               insert newlines between parts
o<esc>                   add an extra line at the end, necessary later...
gugg                     lowercasify everything
j                        go to line 2 (this is why we added the extra line)
<C-v>G                   visual select the first char of all-but-first line
gU                       uppercase
:%s/\n<cr>               join all lines into one

Thanks to Neil for spotting a useless keystroke!

| improve this answer | |
  • \$\begingroup\$ I can see why the last :s has a % but why the inconsistency in the first two? \$\endgroup\$ – Neil Mar 3 '16 at 0:30
  • \$\begingroup\$ @Neil Bah, muscle memory. Thanks! \$\endgroup\$ – Doorknob Mar 3 '16 at 0:53
  • 5
    \$\begingroup\$ Manages to be less readable than Perl, too +1 \$\endgroup\$ – cat Mar 3 '16 at 14:41
  • \$\begingroup\$ I'm totally adding this to my .vimrc \$\endgroup\$ – moopet Mar 4 '16 at 10:58
  • 1
    \$\begingroup\$ @fruglemonkey 1. :%j<cr> is equivalent and shorter. 2. That adds spaces between lines. \$\endgroup\$ – Doorknob Mar 5 '16 at 5:36

Mathematica 10.1, 101 bytes


Uses the undocumented ToCamelCase, which works similarly to Capitalize but sets other characters to lowercase.

| improve this answer | |
  • \$\begingroup\$ Not in 10.3.0.. \$\endgroup\$ – A Simmons Mar 3 '16 at 14:04
  • \$\begingroup\$ Is ToCamelCase[n_,m_]:=n<>Capitalize/@m correct? Seems like it. And why use Prepend when #~ToCamelCase~{##2} works? \$\endgroup\$ – CalculatorFeline Mar 3 '16 at 17:29
  • \$\begingroup\$ @CatsAreFluffy That gives me ToCamelCase::argx: ToCamelCase called with 2 arguments; 1 argument is expected. \$\endgroup\$ – LegionMammal978 Mar 3 '16 at 22:23
  • \$\begingroup\$ Well, how does CamelCase work? Just ToCamelCase[n_]:=""<>Capitalize/@n? \$\endgroup\$ – CalculatorFeline Mar 4 '16 at 16:22
  • \$\begingroup\$ @CatsAreFluffy, see this. \$\endgroup\$ – LegionMammal978 Mar 5 '16 at 1:02

Julia, 98 89 bytes


This is an anonymous function that accepts a string and returns a string. To call it, assign it to a variable.

The approach here is the same as in Doorknob's Perl answer: replace apostrophes and backticks with the empty string, split into an array on a regular expression that matches the necessary cases, map the ucfirst function over the array to uppercase the first letter of each element, join the array back into a string, and lcfirst the result to convert the first character to lowercase.

| improve this answer | |
  • \$\begingroup\$ I've always liked Julia as a more functional, more interesting Python but I hate the end syntax. Maybe I'll just use anonymous functions for everything, then I never have to type end :D \$\endgroup\$ – cat Mar 3 '16 at 14:51

Perl 67 + 1 = 68 bytes

y/'`//d;s/([a-z](?=[A-Z][a-z]))|\W|_/$1 /g;$_=lc;s/^ +| +(.)/\u$1/g

Requires the -p flag, and -l for multi line:

$ perl -pl camelCase.pl input.txt

How it works:

y/'`//d;                            # Remove ' and `
s/([a-z](?=[A-Z][a-z]))|\W|_/$1 /g; # Replace according to '2. Split...' this will create
                                    #   a space separated string.
$_=lc;                              # lower case string
s/^ +| +(.)/\u$1/g                  # CamelCase the space separated string and remove any
                                    #   potential leading spaces.
| improve this answer | |

Perl, 87 80 78 bytes

y/'`//d;$_=join'',map{ucfirst lc}split/[a-z]\K(?=[A-Z][a-z])|\W|_/,$_;lcfirst

Byte added for the -p flag.

First, we use the y/// transliteration operator to delete all '` characters in the input:


Then comes the meat of the code:


(split the input string $_ in the appropriate locations, using the fancy \K in the match string to exclude the portion preceding it from the actual match)

          map{ucfirst lc}

(map over each split portion of the string and make the entire string lowercase, then make the first character of the modified string uppercase)


(join on empty string and re-assign to magic underscore $_, which gets printed at the end)

Finally, we lowercase the first letter by regex-matching it and using \l in the replacement string with a builtin, saving 2 bytes over the previous method:


Thanks to @MartinBüttner for 7 bytes ([^a-zA-Z\d] -> \W|_)!

| improve this answer | |
  • 1
    \$\begingroup\$ How I envy that \K... ;) \$\endgroup\$ – Martin Ender Mar 2 '16 at 20:25

Lua, 127 Bytes

t=''l=t.lower z=io.read()for x in z:gmatch('%w+')do t=t..(t==''and l(x:sub(1,1))or x:sub(1,1):upper())..l(x:sub(2))end return t

Accepts a string from stdin and returns camelized results.

Probably still gonna look for a better solution as storing everything in a variable feels inefficient.

But anyhow, pretty simple in general:


This is the beauty that saved me a bit of bytes. gmatch will split the string based on the pattern: %w+ which grabs only alphanumerics.

After that it's simple string operations. string.upper, string.lower and done.

| improve this answer | |

PHP, 145 122 133 bytes

<?=join(split(" ",lcfirst(ucwords(strtolower(preg_replace(["#`|'#","#\W|_#","#([a-z])([A-Z][a-z])#"],[""," ","$1 $2"],$argv[1]))))));

Save to file, call from CLI.
Takes input from a single command line argument; escape quotes and whitespace where necessary.


<?=                 // 9. print result
join(split(" ",     // 8. remove spaces
    lcfirst(        // 7. lowercase first character
    ucwords(        // 6. uppercase first character in every word
    strtolower(     // 5. lowercase everything
        ["#`|'#",   "#\W|_#",   "#([a-z])([A-Z][a-z])#"],
        ["",        " ",        "$1 $2"],
        // 2. replace apostrophes with empty string (remove them)
                    // 3. replace non-word characters with space
                                // 4. insert space before solitude uppercase
        $argv[1]    // 1. take input from command line

lcfirst allowed to reduce this to a single command, saving 23 bytes.
Fixing the apostrophes cost 11 bytes for the additional replace case.

| improve this answer | |

Kotlin, 160 Bytes

fun a(s: String)=s.replace(Regex("['`]"),"").split(Regex("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])")).map{it.toLowerCase().capitalize()}.joinToString("").decapitalize()

My goal was to be Scala, the other "alternative Java", so I'm somewhat happy with my results. I stole the regex from the Java answer.

Test it with:

fun main(args: Array<String>) {
    val testCases = arrayOf(
            "Programming Puzzles & Code Golf",
            "XML HTTP request",
            "supports IPv6 on iOS?",
            "SomeThing w1th, apo'strophe's and' punc]tuation",
            "nothing special",
            "5pecial ca5e",
    testCases.forEach { println(a(it)) }

| improve this answer | |
  • \$\begingroup\$ At this point I think everyone is "borrowing" the optimized regex \W|_|(?<=[a-z])(?=[A-Z][a-z]) or slightly modifying it eg. [\W_]+ \$\endgroup\$ – CAD97 Mar 4 '16 at 20:54
  • \$\begingroup\$ you can save some on map and extension function fun String.a()=replace(Regex("['`]"),"").split(Regex("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])")).joinToString(""){it.toLowerCase().capitalize()}.decapitalize() \$\endgroup\$ – poss Jan 18 '19 at 11:46

Scala, 181 170 144

def f(s:String)={val l=s.replaceAll("'|`","")split("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])")map(_.toLowerCase);l(0)+l.tail.map(_.capitalize).mkString}


val testCases = List(
  "Programming Puzzles & Code Golf" -> "programmingPuzzlesCodeGolf",
  "XML HTTP request" -> "xmlHttpRequest"
  // etc

Props to CAD97 and apologies to Nathan Merrill :)

| improve this answer | |
  • 1
    \$\begingroup\$ You can save 6 bytes by replacing [^a-zA-Z0-9]+ with [\\W_]+. \$\endgroup\$ – CAD97 Mar 4 '16 at 20:53

C 272 characters

C program pass string to camelCase in quotes as argument 1. There are lot's of gotchas in this problem statement...

#define S strlen(t)
#define A isalnum(t[i])
j=0;main(i,v)char**v;{char*p=v[1],*t;char o[99]={0};while(t=strtok(p," [{(~!@#$%^*-+=)}]")){i=0;p+=S+1;while((!A)&&i<S)i++;if(i!=S){o[j]=((j++==0)?tolower(t[i++]):toupper(t[i++]));while(i<S){if(A)o[j++]=t[i];i++;}}}puts(o);}
| improve this answer | |
  • \$\begingroup\$ You need to #include<string.h> for strlen, strtok, and toupper, and #include<ctype.h> for isalnum. \$\endgroup\$ – Mego Mar 4 '16 at 22:03
  • \$\begingroup\$ I didn't need it using gcc 3.4.4 in cygwin. They must be automatically linked in, assuming extern int. \$\endgroup\$ – cleblanc Mar 4 '16 at 22:05
  • \$\begingroup\$ With ./camel "Programming Puzzles & Code Golf" on cygwin (compiled with gcc 3.4.4), I get programmingPuzzlesCodeEGolf. Same output with 5.3.0. \$\endgroup\$ – Mego Mar 4 '16 at 22:08
  • \$\begingroup\$ Crap. me too. I must've created a bug while golfing it. I'm looking at it now... \$\endgroup\$ – cleblanc Mar 4 '16 at 22:12
  • \$\begingroup\$ The problem was I added the other tokenizer strings after golfing and didn't test it well enough. If you remove the '&' from the strtok call it works on that input. \$\endgroup\$ – cleblanc Mar 4 '16 at 22:26

JavaScript, 123 bytes


Readable version


Remove the apostrophes, make the first character lower case, the last character lowercase, and any grouping of multiple uppercase characters, match any group of 1 or more non-alphanumeric chars + 1 other character, replace with that last character capitalized.

[r="replace"] trick from Mrw247's solution.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.