Camel Case <==> Snake_Case 상호변환하는 코드를 작성해본다.
그리고 이 과정에서 알아낸 replaceAll 의 한계점도 작성해둔다.
참고로 Spring boot(v.2.7.1) 프로젝트 생성 후, Junit5 Test 코드로 짰다.
package hello.dailycode;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.assertj.core.api.Assertions.assertThat;
@Slf4j
public class ConvertingTest {
final String SNAKE_CASE = "good_morning_everyone";
final String CAMEL_CASE = "goodMorningEveryone";
@Test
@DisplayName("snake_case To camelCase")
void name() {
String snake_case = "good_morning_everyone";
Pattern compile = Pattern.compile("([a-z])_([a-z])");
Matcher matcher = compile.matcher(snake_case);
String convert = matcher.replaceAll(matchResult -> {
return String.format(
"%s%s",
matchResult.group(1).toLowerCase(),
matchResult.group(2).toUpperCase()
);
});
log.info("convert result : [{}] ==> [{}]", snake_case, convert);
assertThat(convert).isEqualTo(CAMEL_CASE);
}
@Test
@DisplayName("camelCase To snake_case")
void name2() {
String camelCase = "goodMorningEveryone";
Pattern pattern = Pattern.compile("([a-z])([A-Z])");
Matcher matcher = pattern.matcher(camelCase);
String convert = matcher.replaceAll(matchResult -> {
return String.format("%s_%s", matchResult.group(1), matchResult.group(2));
});
log.info("convert result : [{}] ==> [{}]", camelCase, convert);
assertThat(convert).isEqualTo(SNAKE_CASE);
}
}
package hello.dailycode;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.assertj.core.api.Assertions.assertThat;
@Slf4j
public class ConvertingTest {
final String SNAKE_CASE = "good_morning_everyone";
final String CAMEL_CASE = "goodMorningEveryone";
@Test
@DisplayName("snake_case To camelCase")
void name() {
String snake_case = "good_morning_everyone";
Matcher matcher = Pattern.compile("([a-z])_([a-z])").matcher(snake_case);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String format = String.format(
"%s%s",
matcher.group(1).toLowerCase(),
matcher.group(2).toUpperCase()
);
matcher.appendReplacement(sb,format);
}
StringBuffer stringBuffer = matcher.appendTail(sb);
String convert = stringBuffer.toString();
log.info("convert result : [{}] ==> [{}]", snake_case, convert);
assertThat(convert).isEqualTo(CAMEL_CASE);
}
@Test
@DisplayName("camelCase To snake_case")
void name2() {
String camelCase = "goodMorningEveryone";
Matcher matcher = Pattern.compile("([a-z])([A-Z])").matcher(camelCase);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String format = String.format(
"%s_%s",
matcher.group(1),
matcher.group(2)
);
matcher.appendReplacement(sb,format);
}
StringBuffer stringBuffer = matcher.appendTail(sb);
String convert = stringBuffer.toString().toLowerCase();
log.info("convert result : [{}] ==> [{}]", camelCase, convert);
assertThat(convert).isEqualTo(SNAKE_CASE);
}
}
참고로 camel ==>
snake_case 로 변환하는 건 더 쉬운 방법도 있다.
"goodMorningEveryone".replaceAll("([a-z])([A-Z])", "$1_$2")"
그런데 이 replaceAll(regex, replace)
메서드만으로는 약간의 제약이 있다.
예를 들어 vs code
같은 편집기로 regex replace
기능을 사용할 때,
replace String 으로 "\L$1\U$2"
처럼 특수한 기능을 포함하는 변환 방식을 많이 쓴다.
참고1:
\L
은$1
를 소문자로,\U
는$2
를 대문자로 변환하겠다느 뜻이다.
그런데 이런 특수한 변환 기능은 replaceAll(regex, replace)
에서 지원하지 않는다.
즉, 이 메서드의 2번째 인자값으로 "\\L$1\\U$2"
처럼 사용할 수 없다는 의미다
하지만 이런 특수한 변환이 아니고 그냥 단순 문자열 치환이면 사용해도 무관하다.
참고2:
str.replaceAll(regex, repl)
은
Pattern.compile(regex).matcher(str).replaceAll(repl)
을 요약한 메소드일 뿐이다.
@Slf4j
public class ConvertingTest {
final String SNAKE_CASE = "good_morning_everyone";
final String CAMEL_CASE = "goodMorningEveryone";
@Test
@DisplayName("snake_case To camelCase")
void name() {
String snake_case = "good_morning_everyone";
Matcher matcher = Pattern.compile("([a-z])_([a-z])").matcher(snake_case);
String convert = getConvert(matcher, matchResult -> {
return String.format(
"%s%s",
matcher.group(1).toLowerCase(),
matcher.group(2).toUpperCase()
);
});
log.info("convert result : [{}] ==> [{}]", snake_case, convert);
assertThat(convert).isEqualTo(CAMEL_CASE);
}
@Test
@DisplayName("camelCase To snake_case")
void name2() {
//... 위처럼 작성하면 됩니다. 생략!
}
private String getConvert(Matcher matcher, Function<MatchResult, String> replacer){
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
MatchResult matchResult = matcher.toMatchResult();
String format = replacer.apply(matchResult);
matcher.appendReplacement(sb,format);
}
StringBuffer stringBuffer = matcher.appendTail(sb);
return stringBuffer.toString();
}
}