From d29cd5c9eaf960c5632381b5aa3792acca57aabc Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 17 Aug 2021 16:56:11 +0800 Subject: [PATCH] add NammingCase --- CHANGELOG.md | 1 + .../cn/hutool/core/text/CharSequenceUtil.java | 82 +------- .../java/cn/hutool/core/text/NamingCase.java | 179 ++++++++++++++++++ 3 files changed, 186 insertions(+), 76 deletions(-) create mode 100644 hutool-core/src/main/java/cn/hutool/core/text/NamingCase.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 19a077ca0..19525228c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ # 5.7.10 (2021-08-17) ### 🐣新特性 +* 【core 】 增加NamingCase类 ### 🐞Bug修复 ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java index 2f3e152bb..c9d1b4a25 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java @@ -4016,9 +4016,10 @@ public class CharSequenceUtil { * * @param str 转换前的驼峰式命名的字符串,也可以为下划线形式 * @return 转换后下划线方式命名的字符串 + * @see NamingCase#toUnderlineCase(CharSequence) */ public static String toUnderlineCase(CharSequence str) { - return toSymbolCase(str, CharUtil.UNDERLINE); + return NamingCase.toUnderlineCase(str); } /** @@ -4028,58 +4029,10 @@ public class CharSequenceUtil { * @param symbol 连接符 * @return 转换后符号连接方式命名的字符串 * @since 4.0.10 + * @see NamingCase#toSymbolCase(CharSequence, char) */ public static String toSymbolCase(CharSequence str, char symbol) { - if (str == null) { - return null; - } - - final int length = str.length(); - final StrBuilder sb = new StrBuilder(); - char c; - for (int i = 0; i < length; i++) { - c = str.charAt(i); - if (Character.isUpperCase(c)) { - final Character preChar = (i > 0) ? str.charAt(i - 1) : null; - final Character nextChar = (i < str.length() - 1) ? str.charAt(i + 1) : null; - - if (null != preChar) { - if (symbol == preChar) { - // 前一个为分隔符 - if (null == nextChar || Character.isLowerCase(nextChar)) { - //普通首字母大写,如_Abb -> _abb - c = Character.toLowerCase(c); - } - //后一个为大写,按照专有名词对待,如_AB -> _AB - } else if (Character.isLowerCase(preChar)) { - // 前一个为小写 - sb.append(symbol); - if (null == nextChar || Character.isLowerCase(nextChar)) { - //普通首字母大写,如aBcc -> a_bcc - c = Character.toLowerCase(c); - } - // 后一个为大写,按照专有名词对待,如aBC -> a_BC - } else { - //前一个为大写 - if (null == nextChar || Character.isLowerCase(nextChar)) { - // 普通首字母大写,如ABcc -> A_bcc - sb.append(symbol); - c = Character.toLowerCase(c); - } - // 后一个为大写,按照专有名词对待,如ABC -> ABC - } - } else { - // 首字母,需要根据后一个判断是否转为小写 - if (null == nextChar || Character.isLowerCase(nextChar)) { - // 普通首字母大写,如Abc -> abc - c = Character.toLowerCase(c); - } - // 后一个为大写,按照专有名词对待,如ABC -> ABC - } - } - sb.append(c); - } - return sb.toString(); + return NamingCase.toSymbolCase(str, symbol); } /** @@ -4088,33 +4041,10 @@ public class CharSequenceUtil { * * @param name 转换前的下划线大写方式命名的字符串 * @return 转换后的驼峰式命名的字符串 + * @see NamingCase#toCamelCase(CharSequence) */ public static String toCamelCase(CharSequence name) { - if (null == name) { - return null; - } - - final String name2 = name.toString(); - if (contains(name2, CharUtil.UNDERLINE)) { - final int length = name2.length(); - final StringBuilder sb = new StringBuilder(length); - boolean upperCase = false; - for (int i = 0; i < length; i++) { - char c = name2.charAt(i); - - if (c == CharUtil.UNDERLINE) { - upperCase = true; - } else if (upperCase) { - sb.append(Character.toUpperCase(c)); - upperCase = false; - } else { - sb.append(Character.toLowerCase(c)); - } - } - return sb.toString(); - } else { - return name2; - } + return NamingCase.toCamelCase(name); } // ------------------------------------------------------------------------ isSurround diff --git a/hutool-core/src/main/java/cn/hutool/core/text/NamingCase.java b/hutool-core/src/main/java/cn/hutool/core/text/NamingCase.java new file mode 100644 index 000000000..2c720967f --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/text/NamingCase.java @@ -0,0 +1,179 @@ +package cn.hutool.core.text; + +import cn.hutool.core.util.CharUtil; +import cn.hutool.core.util.StrUtil; + +/** + * 命名规则封装,主要是针对驼峰风格命名、连接符命名等的封装 + * + * @author looly + * @since 5.7.10 + */ +public class NamingCase { + + /** + * 将驼峰式命名的字符串转换为下划线方式,又称SnakeCase、underScoreCase。
+ * 如果转换前的驼峰式命名的字符串为空,则返回空字符串。
+ * 规则为: + * + * 例如: + * + *
+	 * HelloWorld=》hello_world
+	 * Hello_World=》hello_world
+	 * HelloWorld_test=》hello_world_test
+	 * 
+ * + * @param str 转换前的驼峰式命名的字符串,也可以为下划线形式 + * @return 转换后下划线方式命名的字符串 + */ + public static String toUnderlineCase(CharSequence str) { + return toSymbolCase(str, CharUtil.UNDERLINE); + } + + /** + * 将驼峰式命名的字符串转换为短横连接方式。
+ * 如果转换前的驼峰式命名的字符串为空,则返回空字符串。
+ * 规则为: + * + * 例如: + * + *
+	 * HelloWorld=》hello-world
+	 * Hello_World=》hello-world
+	 * HelloWorld_test=》hello-world-test
+	 * 
+ * + * @param str 转换前的驼峰式命名的字符串,也可以为下划线形式 + * @return 转换后下划线方式命名的字符串 + */ + public static String toKebabCase(CharSequence str) { + return toSymbolCase(str, CharUtil.DASHED); + } + + /** + * 将驼峰式命名的字符串转换为使用符号连接方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。
+ * + * @param str 转换前的驼峰式命名的字符串,也可以为符号连接形式 + * @param symbol 连接符 + * @return 转换后符号连接方式命名的字符串 + * @since 4.0.10 + */ + public static String toSymbolCase(CharSequence str, char symbol) { + if (str == null) { + return null; + } + + final int length = str.length(); + final StrBuilder sb = new StrBuilder(); + char c; + for (int i = 0; i < length; i++) { + c = str.charAt(i); + if (Character.isUpperCase(c)) { + final Character preChar = (i > 0) ? str.charAt(i - 1) : null; + final Character nextChar = (i < str.length() - 1) ? str.charAt(i + 1) : null; + + if (null != preChar) { + if (symbol == preChar) { + // 前一个为分隔符 + if (null == nextChar || Character.isLowerCase(nextChar)) { + //普通首字母大写,如_Abb -> _abb + c = Character.toLowerCase(c); + } + //后一个为大写,按照专有名词对待,如_AB -> _AB + } else if (Character.isLowerCase(preChar)) { + // 前一个为小写 + sb.append(symbol); + if (null == nextChar || Character.isLowerCase(nextChar)) { + //普通首字母大写,如aBcc -> a_bcc + c = Character.toLowerCase(c); + } + // 后一个为大写,按照专有名词对待,如aBC -> a_BC + } else { + //前一个为大写 + if (null == nextChar || Character.isLowerCase(nextChar)) { + // 普通首字母大写,如ABcc -> A_bcc + sb.append(symbol); + c = Character.toLowerCase(c); + } + // 后一个为大写,按照专有名词对待,如ABC -> ABC + } + } else { + // 首字母,需要根据后一个判断是否转为小写 + if (null == nextChar || Character.isLowerCase(nextChar)) { + // 普通首字母大写,如Abc -> abc + c = Character.toLowerCase(c); + } + // 后一个为大写,按照专有名词对待,如ABC -> ABC + } + } + sb.append(c); + } + return sb.toString(); + } + + /** + * 将下划线方式命名的字符串转换为帕斯卡式。
+ * 规则为: + * + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world=》HelloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String toPascalCase(CharSequence name) { + return StrUtil.upperFirst(toCamelCase(name)); + } + + /** + * 将下划线方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 规则为: + * + * 例如:hello_world=》helloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String toCamelCase(CharSequence name) { + if (null == name) { + return null; + } + + final String name2 = name.toString(); + if (StrUtil.contains(name2, CharUtil.UNDERLINE)) { + final int length = name2.length(); + final StringBuilder sb = new StringBuilder(length); + boolean upperCase = false; + for (int i = 0; i < length; i++) { + char c = name2.charAt(i); + + if (c == CharUtil.UNDERLINE) { + upperCase = true; + } else if (upperCase) { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } else { + sb.append(Character.toLowerCase(c)); + } + } + return sb.toString(); + } else { + return name2; + } + } +}