1. 개요
소프트웨어를 개발할 때 문자열의 명명 형식(String Naming Type)을 변환해야 할 경우가 왕왕 있었는데, 이에 따라 자유자재로 변환이 가능한 Utilty 기능의 필요성을 느껴 개발하였고 이 포스팅에서 소개하고자 한다.
1.1. 명명 형식 종류
명명 형식 | 예시 |
---|---|
Lower Snake Case | hello_world |
Upper Snake Case | HELLO_WORLD |
Lower Skewer Case | hello-world |
Upper Skewer Case | HELLO-WORLD |
Pascal Case | HelloWorld |
Camel Case | helloWorld |
Title Case | Hello World |
Lower Case | hello world |
Upper Case | HELLO WORLD |
2. 활용 문법
2.1. extension
2.2. get
3. 구현
3.1. 열거형 (Enum)
명명 형식의 종류를 나타내는 열거형 StringCaseType
이다.
enum StringCaseType {
lowerSnakeCase, upperSnakeCase,
lowerSkewerCase, upperSkewerCase,
pascalCase, camelCase,
titleCase, lowerCase, upperCase;
}
3.2. 클래스 (Class)
3.2.1. 생성자 (Constructor)
전달받은 value
매개변수가 어떤 종류인지 파악하여 해당 종류에 대한 Setter 를 사용해 _value
값을 최신화한다.
StringCaseConverter(String value) {
var type = getCaseType(value);
switch (type) {
case StringCaseType.lowerSnakeCase: lowerSnakeCase = value; break;
case StringCaseType.upperSnakeCase: upperSnakeCase = value; break;
case StringCaseType.lowerSkewerCase: lowerSkewerCase = value; break;
case StringCaseType.upperSkewerCase: upperSkewerCase = value; break;
case StringCaseType.pascalCase: pascalCase = value; break;
case StringCaseType.camelCase: camelCase = value; break;
case StringCaseType.titleCase: titleCase = value; break;
case StringCaseType.lowerCase: lowerCase = value; break;
case StringCaseType.upperCase: upperCase = value; break;
default: throw ArgumentError('Unknown case type for: $value');
}
}
3.2.2. _value
속성
StringCaseConverter
클래스가 가지는 유일한 속성으로 Lower Snake Case 형식으로 저장된다.
late String _value;
3.2.3. 접근자 (Accessor), 설정자 (Mutator)
/// lower_snake_case
String get lowerSnakeCase => _value;
set lowerSnakeCase(String s) => _value = s;
/// UPPER_SNAKE_CASE
String get upperSnakeCase => _value.toUpperCase();
set upperSnakeCase(String s) => _value = s.toLowerCase();
/// lower_skewer_case
String get lowerSkewerCase => _value.replaceAll('_', '-');
set lowerSkewerCase(String s) => _value = s.replaceAll('-', '_');
/// UPPER_SKEWER_CASE
String get upperSkewerCase => lowerSkewerCase.toUpperCase();
set upperSkewerCase(String s) => lowerSkewerCase = s.toLowerCase();
/// PascalCase
String get pascalCase {
final words = _splitToWords(_value);
return words.map(_capitalizeFirstLetter).join();
}
set pascalCase(String s) {
final words = _splitToWords(s);
_value = words.map((word) => word.toLowerCase()).join('_');
}
/// camelCase
String get camelCase {
final words = _splitToWords(_value);
return [words.first.toLowerCase(), ...words.skip(1).map(_capitalizeFirstLetter)].join();
}
set camelCase(String s) {
final words = _splitToWords(s);
_value = words.map((word) => word.toLowerCase()).join('_');
}
/// Title Case
String get titleCase {
final words = _splitToWords(_value.replaceAll('_', ' ').replaceAll('-', ' '));
return words.map(_capitalizeFirstLetter).join(' ');
}
set titleCase(String s) {
final words = s.split(RegExp(r'\s+'));
_value = words.map((word) => word.toLowerCase()).join('_');
}
/// lower case
String get lowerCase => titleCase.toLowerCase();
set lowerCase(String s) => titleCase = s.toLowerCase();
/// UPPER CASE
String get upperCase => titleCase.toUpperCase();
set upperCase(String s) => titleCase = s.toUpperCase();
3.2.4. 정적 메소드 (Static Method)
3.2.4.1. getCaseType()
문자열 str 의 명명 형식을 반환한다.
- 매개변수
자료형 | 변수명 | 설명 |
---|---|---|
String |
str | 명명 형식을 조사할 문자열 |
- 반환값
자료형 | 설명 |
---|---|
StringCaseType |
str 의 명명 형식 |
static StringCaseType getCaseType(String str) {
var isLower = str == str.toLowerCase();
var isUpper = str == str.toUpperCase();
var hasUnderscore = str.contains('_');
var hasHyphen = str.contains('-');
var hasSpace = str.contains(' ');
/// 모든 문자가 소문자인 경우
if (isLower) {
if (hasUnderscore) return StringCaseType.lowerSnakeCase;
if (hasHyphen) return StringCaseType.lowerSkewerCase;
return StringCaseType.lowerCase;
}
/// 모든 문자가 대문자인 경우
else if (isUpper) {
if (hasUnderscore) return StringCaseType.upperSnakeCase;
if (hasHyphen) return StringCaseType.upperSkewerCase;
return StringCaseType.upperCase;
}
/// 소문자와 대문자가 섞인 경우
else {
var firstChar = str[0];
var isFirstCharUpper = firstChar.toUpperCase() == firstChar;
var isFirstCharLower = firstChar.toLowerCase() == firstChar;
if (hasSpace) return StringCaseType.titleCase;
if (isFirstCharUpper && !hasUnderscore && !hasHyphen) return StringCaseType.pascalCase;
if (isFirstCharLower && !hasUnderscore && !hasHyphen) return StringCaseType.camelCase;
}
throw ArgumentError('Unknown case type for: $str');
}
3.2.4.2. _splitToWords()
문자열 str
을 -
또는 _
를 구분자로 하여 단어별로 구분한 배열을 반환한다.
- 매개변수
자료형 | 변수명 | 설명 |
---|---|---|
String |
str | 단어별로 구분할 문자열 |
- 반환값
자료형 | 설명 |
---|---|
List<String> |
str 를 단어별로 구분한 배열 |
static List<String> _splitToWords(String str) {
final pattern = RegExp(r'[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|$)|\d+');
final matches = pattern.allMatches(str.replaceAll(RegExp(r'[-_]'), ' '));
return matches.map((m) => m.group(0) ?? '').toList();
}
3.2.4.3. _capitalizeFirstLetter()
문자열 str 의 첮 문자를 대문자로 바꾼다.
- 매개변수
자료형 | 변수명 | 설명 |
---|---|---|
String |
str | 첫 문자를 대문자로 바꿀 문자열 |
- 반환값
자료형 | 설명 |
---|---|
String |
str 의 첫 문자를 대문자로 바꾼 문자열 |
static String _capitalizeFirstLetter(String str) {
if (str.isEmpty) return str;
return str[0].toUpperCase() + str.substring(1).toLowerCase();
}
4. 전체 코드
enum StringCaseType {
lowerSnakeCase, upperSnakeCase,
lowerSkewerCase, upperSkewerCase,
pascalCase, camelCase,
titleCase, lowerCase, upperCase;
}
class StringCaseConverter {
StringCaseConverter(String value) {
var type = getCaseType(value);
switch (type) {
case StringCaseType.lowerSnakeCase: lowerSnakeCase = value; break;
case StringCaseType.upperSnakeCase: upperSnakeCase = value; break;
case StringCaseType.lowerSkewerCase: lowerSkewerCase = value; break;
case StringCaseType.upperSkewerCase: upperSkewerCase = value; break;
case StringCaseType.pascalCase: pascalCase = value; break;
case StringCaseType.camelCase: camelCase = value; break;
case StringCaseType.titleCase: titleCase = value; break;
case StringCaseType.lowerCase: lowerCase = value; break;
case StringCaseType.upperCase: upperCase = value; break;
default: throw ArgumentError('Unknown case type for: $value');
}
}
/// default: lower_snake_case
late String _value;
/// lower_snake_case
String get lowerSnakeCase => _value;
set lowerSnakeCase(String s) => _value = s;
/// UPPER_SNAKE_CASE
String get upperSnakeCase => _value.toUpperCase();
set upperSnakeCase(String s) => _value = s.toLowerCase();
/// lower_skewer_case
String get lowerSkewerCase => _value.replaceAll('_', '-');
set lowerSkewerCase(String s) => _value = s.replaceAll('-', '_');
/// UPPER_SKEWER_CASE
String get upperSkewerCase => lowerSkewerCase.toUpperCase();
set upperSkewerCase(String s) => lowerSkewerCase = s.toLowerCase();
/// PascalCase
String get pascalCase {
final words = _splitToWords(_value);
return words.map(_capitalizeFirstLetter).join();
}
set pascalCase(String s) {
final words = _splitToWords(s);
_value = words.map((word) => word.toLowerCase()).join('_');
}
/// camelCase
String get camelCase {
final words = _splitToWords(_value);
return [words.first.toLowerCase(), ...words.skip(1).map(_capitalizeFirstLetter)].join();
}
set camelCase(String s) {
final words = _splitToWords(s);
_value = words.map((word) => word.toLowerCase()).join('_');
}
/// Title Case
String get titleCase {
final words = _splitToWords(_value.replaceAll('_', ' ').replaceAll('-', ' '));
return words.map(_capitalizeFirstLetter).join(' ');
}
set titleCase(String s) {
final words = s.split(RegExp(r'\s+'));
_value = words.map((word) => word.toLowerCase()).join('_');
}
/// lower case
String get lowerCase => titleCase.toLowerCase();
set lowerCase(String s) => titleCase = s.toLowerCase();
/// UPPER CASE
String get upperCase => titleCase.toUpperCase();
set upperCase(String s) => titleCase = s.toUpperCase();
static StringCaseType getCaseType(String str) {
var isLower = str == str.toLowerCase();
var isUpper = str == str.toUpperCase();
var hasUnderscore = str.contains('_');
var hasHyphen = str.contains('-');
var hasSpace = str.contains(' ');
/// 모든 문자가 소문자인 경우
if (isLower) {
if (hasUnderscore) return StringCaseType.lowerSnakeCase;
if (hasHyphen) return StringCaseType.lowerSkewerCase;
return StringCaseType.lowerCase;
}
/// 모든 문자가 대문자인 경우
else if (isUpper) {
if (hasUnderscore) return StringCaseType.upperSnakeCase;
if (hasHyphen) return StringCaseType.upperSkewerCase;
return StringCaseType.upperCase;
}
/// 소문자와 대문자가 섞인 경우
else {
var firstChar = str[0];
var isFirstCharUpper = firstChar.toUpperCase() == firstChar;
var isFirstCharLower = firstChar.toLowerCase() == firstChar;
if (hasSpace) return StringCaseType.titleCase;
if (isFirstCharUpper && !hasUnderscore && !hasHyphen) return StringCaseType.pascalCase;
if (isFirstCharLower && !hasUnderscore && !hasHyphen) return StringCaseType.camelCase;
}
throw ArgumentError('Unknown case type for: $str');
}
static List<String> _splitToWords(String str) {
final pattern = RegExp(r'[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|$)|\d+');
final matches = pattern.allMatches(str.replaceAll(RegExp(r'[-_]'), ' '));
return matches.map((m) => m.group(0) ?? '').toList();
}
static String _capitalizeFirstLetter(String str) {
if (str.isEmpty) return str;
return str[0].toUpperCase() + str.substring(1).toLowerCase();
}
}
5. 사용법
void main() {
print(StringCaseConverter('hello_world').pascalCase); // HelloWorld
print(StringCaseConverter('HELLO_WORLD').pascalCase); // HelloWorld
print(StringCaseConverter('hello-world').pascalCase); // HelloWorld
print(StringCaseConverter('HELLO-WORLD').pascalCase); // HelloWorld
print(StringCaseConverter('HelloWorld').pascalCase); // HelloWorld
print(StringCaseConverter('helloWorld').pascalCase); // HelloWorld
print(StringCaseConverter('Hello World').pascalCase); // HelloWorld
print(StringCaseConverter('hello world').pascalCase); // HelloWorld
print(StringCaseConverter('HELLO WORLD').pascalCase); // HelloWorld
print(StringCaseConverter('hello_world').lowerSnakeCase); // hello_world
print(StringCaseConverter('hello_world').upperSnakeCase); // HELLO_WORLD
print(StringCaseConverter('hello_world').lowerSkewerCase); // hello-world
print(StringCaseConverter('hello_world').upperSkewerCase); // HELLO-WORLD
print(StringCaseConverter('hello_world').pascalCase); // HelloWorld
print(StringCaseConverter('hello_world').camelCase); // helloWorld
print(StringCaseConverter('hello_world').titleCase); // Hello World
print(StringCaseConverter('hello_world').lowerCase); // hello world
print(StringCaseConverter('hello_world').upperCase); // HELLO WORLD
}
관련 링크
728x90
'Develop > Flutter' 카테고리의 다른 글
[Flutter] 한글 Utility 기능 (0) | 2025.01.28 |
---|---|
[Flutter] Duration 값 간결히 나타내기 (0) | 2023.11.01 |
[Flutter] 순환 캐러셀 (Circular Carousel) 위젯 만들기 (0) | 2023.10.16 |
[Flutter] 토스 스타일의 Pressable 커스텀 위젯 만들기 (0) | 2023.09.23 |