To improve(?) https://vladmihalcea.com/map-camel-case-properties-snake-case-column-names-hibernate/, https://github.com/vladmihalcea/hibernate-types/blob/master/hibernate-types-52/src/main/java/com/vladmihalcea/hibernate/type/util/CamelCaseToSnakeCaseNamingStrategy.java
Essentially based on splitByCharacterTypeCamelCase() code at https://git-wip-us.apache.org/repos/asf?p=commons-lang.git;a=blob;f=src/main/java/org/apache/commons/lang3/StringUtils.java;h=12dfcdca70d0bf61dca2cab5dcce9e29bb5a4dfb;hb=HEAD . Just pastes digits to previous tokens...
import static java.lang.Character.*;
import static java.lang.System.out;
import static java.util.stream.Stream.of;
import static org.apache.commons.lang3.StringUtils.join;
import static org.apache.commons.lang3.StringUtils.splitByCharacterTypeCamelCase;
public class CamelCaseToSnakeCase {
private static final String SNAKE_CASE_PATTERN = "$1\\_$2";
private static final String CAMEL_CASE_REGEX = "([a-z]+)([A-Z]+)";
private static final String CAMEL_CASE_REGEX_2 = "([\\p{Lower}\\p{Digit}]+)(\\p{Upper}+)";
private static String splitJoinParts(String identifier, String separator) {
if (identifier == null || identifier.isEmpty()) {
return identifier;
}
if (separator == null) {
separator = "";
}
final char[] chars = identifier.toCharArray();
final StringBuilder acc = new StringBuilder();
int tknStart = 0;
int currType = getType(chars[tknStart]);
for (int pos = tknStart + 1; pos < chars.length; pos++) {
final int type = getType(chars[pos]);
if (type == DECIMAL_DIGIT_NUMBER || type == currType) {
continue; // also paste digits to the previous token
}
if (type == LOWERCASE_LETTER && currType == UPPERCASE_LETTER) {
final int newTknStart = pos - 1;
if (newTknStart != tknStart) {
(acc.length() == 0 ? acc : acc.append(separator)).append(chars, tknStart, newTknStart - tknStart);
tknStart = newTknStart;
}
} else {
(acc.length() == 0 ? acc : acc.append(separator)).append(chars, tknStart, pos - tknStart);
tknStart = pos;
}
currType = type;
}
final int charsLeft = chars.length - tknStart;
return (charsLeft > 0 ? (acc.length() == 0 ? acc : acc.append(separator)).append(chars, tknStart, charsLeft)
: acc).toString();
}
public static void main(String[] args) {
of("a", "firstName", "last", "doc2Id", "oneTwoThree", "oneTwoTHREEFour", "oneTwoTHREE30Four", "abC")
.forEach(id -> {
out.println();
out.println(id.replaceAll(CAMEL_CASE_REGEX, SNAKE_CASE_PATTERN).toLowerCase());
out.println(id.replaceAll(CAMEL_CASE_REGEX_2, SNAKE_CASE_PATTERN).toLowerCase());
out.println(join(splitByCharacterTypeCamelCase(id), "_"));
out.println(splitJoinParts(id, "_").toLowerCase());
});
}
}