Skip to content

Instantly share code, notes, and snippets.

@Techcable
Created January 27, 2026 17:27
Show Gist options
  • Select an option

  • Save Techcable/da5b9871f26e1a91874f095b6e39be48 to your computer and use it in GitHub Desktop.

Select an option

Save Techcable/da5b9871f26e1a91874f095b6e39be48 to your computer and use it in GitHub Desktop.
import java.util.Locale;
/// Utilities for case conversion
public class CaseConversion {
private CaseConversion() {
}
public static String convertPascalCaseToSnakeCase(String pascalCase) {
if (pascalCase.indexOf('_') >= 0) return pascalCase; // already converted
StringBuilder res = new StringBuilder();
int currentIndex = 0;
while (currentIndex < pascalCase.length()) {
int regionStart = currentIndex;
int regionEnd = regionStart;
int leadingUpperChars = 0;
// skip over uppercase characters at the beginning of the region
for (int cp; regionEnd < pascalCase.length() && Character.isUpperCase(cp = pascalCase.codePointAt(regionEnd)); ) {
regionEnd += Character.charCount(cp);
leadingUpperChars += 1;
}
// if the region ends at the end of the string, we don't want to shrink or extend it
if (regionEnd < pascalCase.length()) {
// if we have multiple uppercase characters at the start,
// they are treated as their own region,
// with the final char removed
if (leadingUpperChars > 1) {
regionEnd = pascalCase.offsetByCodePoints(regionEnd, -1);
} else {
// expand region to include all remaining lowercase characters
int cp;
while (regionEnd < pascalCase.length() && Character.isLowerCase(cp = pascalCase.codePointAt(regionEnd))) {
regionEnd += Character.charCount(cp);
}
}
}
String region = pascalCase.substring(regionStart, regionEnd);
if (!res.isEmpty()) res.append("_");
res.append(region.toLowerCase(Locale.ROOT));
currentIndex = regionEnd;
}
return res.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment