'Is there any simple way to convert camel-case to snake-case correctly?

I tried as the below code code snippet, but the TradeID is printing as Trade_I_D, but it must be as Trade_ID.

  • input: getCurrency, getAccountName, getTradeID
  • expected output: Currency, Account_Name, Trade_ID
public class RemoveGet {

    public static void main(String args[]) {
        for (String a : args) {
            String b = a.replace("get", "");
            //System.out.println(b);
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < b.length(); i++) {
                if (Character.isUpperCase(b.charAt(i))) {
                    sb.append("_");
                    sb.append(b.charAt(i));
                } else {
                    sb.append(b.charAt(i));
                }
            }
            //System.out.println(sb.toString());
            String c = sb.toString();
            if (c.startsWith("_")) {
                System.out.println(c.substring(1));
            }
        }
    }
}



Solution 1:[1]

Use a boolean first-time switch to only put an underscore after the second upper case letter.

Here are some test results.

getTradeID
Trade_ID

Here's the complete runnable code.

public class RemoveGet {

    public static void main(String args[]) {
        args = new String[1];
        args[0] = "getTradeID";
        
        for (String a : args) {
            System.out.println(a);
            String b = a.replace("get", "");
            boolean firstTimeSwitch = true;
//          System.out.println(b);
            StringBuffer sb = new StringBuffer();
            sb.append(b.charAt(0));
            
            for (int i = 1; i < b.length(); i++) {
                if (firstTimeSwitch && Character.isUpperCase(b.charAt(i))) {
                    sb.append("_");
                    sb.append(b.charAt(i));
                    firstTimeSwitch = false;
                } else {
                    sb.append(b.charAt(i));
                }
            }
            
            System.out.println(sb.toString());
        }
    }

}

Solution 2:[2]

try this

str = str.replace("get", "")
    .replaceAll("([A-Z]+)([A-Z][a-z])", "$1_$2")
    .replaceAll("([a-z])([A-Z])", "$1_$2")

Solution 3:[3]

Instead of writing all logic in the main function, write some functions to do small tasks and call them in the main function. This makes the code readable and easy to debug. This could be the possible solution code:

public class RemoveGet {

 public static String addUnderScoreAppropriately(String input) {
     String result = "";
     String underScore = "_";
     for(int i=0; i<input.length();i++) {
         if((Character.isUpperCase(input.charAt(i))) && (i != 0)) {
             result = result + underScore + input.charAt(i);
         }else{
             result = result + input.charAt(i);
         }
     }
     result = result.replace("_I_D","_ID");
     return result;
 }

 public static void main(String args[]) {
    for (String a : args) {
        System.out.println(addUnderScoreAppropriately(a.replace("get","")));
    }
 }

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Gilbert Le Blanc
Solution 2
Solution 3 Deepeshkumar