Convert to camelCase 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:


Remove all apostrophes `'
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

Lowercase every word.
Uppercase the first character of every but the first word.
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.


Rules


Function or full program allowed.
Default rules for input/output.
Standard loopholes apply.
This is code-golf, so lowest byte-count wins. Tiebreaker is earlier submission.


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!
Retina, 56 bytes

Byte count assumes ISO 8859-1 encoding.

T`'\`
S_`\W|_|(?&lt;=[a-z])(?=[A-Z][a-z])
T`L`l
T`l`L`¶.
¶



Try it online!

Explanation

This implements the specification quite literally:

T`'\`


Remove apostrophes and backticks.

S_`\W|_|(?&lt;=[a-z])(?=[A-Z][a-z])


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.

T`L`l


Convert everything to lower case.

T`l`L`¶.


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.