octavian-nita
11/15/2018 - 4:05 PM

Camel case to snake case strategies...

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());
            });
    }
}