Every case-conversion tool has to solve the same problem before it can do any converting: figure out where one word ends and the next begins. For snake_case and kebab-case that's trivial — split on _ or -. For camelCase and PascalCase there's no separator character at all, just a change from lowercase to uppercase, which is where a naive converter starts making mistakes.
The two boundary rules
Word-splitting here runs on two regular expressions, applied in sequence. The first catches the ordinary case: a lowercase letter or digit immediately followed by an uppercase letter is a boundary — myVariable splits into my and Variable. The second catches acronyms: a run of two or more uppercase letters followed by an uppercase-then-lowercase pair is also a boundary, placed before the last capital in the run:
XMLParser
↓ (first rule finds no lowercase-to-uppercase transition — it's all caps until "arser")
↓ (second rule: "XMLP" is a run of capitals, followed by "Pa" — split before the "P")
XML ParserWithout that second rule, XMLParser would split at every capital and produce x_m_l_parser instead of the correct xml_parser. Getting the acronym boundary one letter too early or too late is the single most common bug in hand-rolled case converters.
An acronym at the end of a word doesn't split
convertURL only has one boundary: the lowercase t before the uppercase U. Nothing inside URL triggers a split, because there's no lowercase letter after it to signal "the acronym just ended." That's correct — convertURL should become convert_url, not convert_u_r_l — but it also means a trailing acronym gets lowercased as a single unit, which is usually what you want and occasionally isn't (a REST API that specifically wants URL capitalized in a constant name has to be fixed by hand afterward).
Digits stay attached to the word they're part of
A digit is treated the same as a lowercase letter for boundary purposes, not as its own category. value2Count splits at the lowercase-to-uppercase transition between 2 and C (giving value2 and Count), but a digit sitting between two letters of the same case doesn't create a boundary on its own:
value2Count → value2 / Count → value2_count item9 → item9 → item9 h2oLevel → h2o / Level → h2o_level
Where this actually matters: API boundaries
The recurring real-world reason to reach for this tool isn't style preference — it's translating field names across a boundary where the convention changes. A Python or Ruby backend returning snake_case JSON keys into a JavaScript frontend that wants camelCase object properties is the most common version of this. Converting a handful of field names by hand is fine; a payload with forty fields is exactly when a converter that gets acronyms and digits right (rather than 90%-right) earns its keep — a single mis-split key silently becomes a property your code can't find.