diff --git a/CHANGELOG.md b/CHANGELOG.md index f653f3f09..dbc471984 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.7.14 (2021-10-08) +# 5.7.14 (2021-10-09) ### 🐣新特性 * 【extra 】 修复HttpCookie设置cookies的方法,不符合RFC6265规范问题(issue#I4B70D@Gitee) @@ -16,13 +16,13 @@ * 【core 】 DateTime构造和DateUtil.parse可选是否宽松模式(issue#1849@Github) * 【core 】 TreeBuilder增加部分根节点set方法(issue#1848@Github) * 【core 】 优化Base64.isBase64方法:减少一次多余的判断(pr#1860@Github) -* 【core 】 优化Base64.isBase64方法:减少一次多余的判断(pr#1860@Github) * 【cache 】 优化FIFOCache未设置过期策略时,无需遍历判断过期对象(pr#425@Gitee) * 【core 】 增加Opt类(pr#426@Gitee) * 【core 】 Week增加of重载,支持DayOfWek(pr#1872@Github) * 【poi 】 优化read,避免多次创建CopyOptions(issue#1875@Github) * 【core 】 优化CsvReader,实现可控遍历(pr#1873@Github) * 【core 】 优化Base64.isBase64判断(pr#1879@Github) +* 【core 】 新增StrFormatter.formatWith(pr#430@Gitee) ### 🐞Bug修复 * 【http 】 修复HttpCookie设置cookies的方法,不符合RFC6265规范问题(pr#418@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/text/StrFormatter.java b/hutool-core/src/main/java/cn/hutool/core/text/StrFormatter.java index cc5ec7cc5..a70d5542f 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/StrFormatter.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/StrFormatter.java @@ -9,7 +9,6 @@ import java.util.Map; * 字符串格式化工具 * * @author Looly - * */ public class StrFormatter { @@ -23,22 +22,42 @@ public class StrFormatter { * 转义\: format("this is \\\\{} for {}", "a", "b") =》 this is \a for b
* * @param strPattern 字符串模板 - * @param argArray 参数列表 + * @param argArray 参数列表 * @return 结果 */ - public static String format(final String strPattern, final Object... argArray) { - if (StrUtil.isBlank(strPattern) || ArrayUtil.isEmpty(argArray)) { + public static String format(String strPattern, Object... argArray) { + return formatWith(strPattern, StrUtil.EMPTY_JSON, argArray); + } + + /** + * 格式化字符串
+ * 此方法只是简单将指定占位符 按照顺序替换为参数
+ * 如果想输出占位符使用 \\转义即可,如果想输出占位符之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "{}", "a", "b") =》 this is a for b
+ * 转义{}: format("this is \\{} for {}", "{}", "a", "b") =》 this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "{}", "a", "b") =》 this is \a for b
+ * + * @param strPattern 字符串模板 + * @param placeHolder 占位符,例如{} + * @param argArray 参数列表 + * @return 结果 + * @since 5.7.14 + */ + public static String formatWith(String strPattern, String placeHolder, Object... argArray) { + if (StrUtil.isBlank(strPattern) || StrUtil.isBlank(placeHolder) || ArrayUtil.isEmpty(argArray)) { return strPattern; } final int strPatternLength = strPattern.length(); + final int placeHolderLength = placeHolder.length(); // 初始化定义好的长度以获得更好的性能 - StringBuilder sbuf = new StringBuilder(strPatternLength + 50); + final StringBuilder sbuf = new StringBuilder(strPatternLength + 50); int handledPosition = 0;// 记录已经处理到的位置 int delimIndex;// 占位符所在位置 for (int argIndex = 0; argIndex < argArray.length; argIndex++) { - delimIndex = strPattern.indexOf(StrUtil.EMPTY_JSON, handledPosition); + delimIndex = strPattern.indexOf(placeHolder, handledPosition); if (delimIndex == -1) {// 剩余部分无占位符 if (handledPosition == 0) { // 不带占位符的模板直接返回 return strPattern; @@ -54,24 +73,23 @@ public class StrFormatter { // 转义符之前还有一个转义符,占位符依旧有效 sbuf.append(strPattern, handledPosition, delimIndex - 1); sbuf.append(StrUtil.utf8Str(argArray[argIndex])); - handledPosition = delimIndex + 2; + handledPosition = delimIndex + placeHolderLength; } else { // 占位符被转义 argIndex--; sbuf.append(strPattern, handledPosition, delimIndex - 1); - sbuf.append(StrUtil.C_DELIM_START); + sbuf.append(placeHolder.charAt(0)); handledPosition = delimIndex + 1; } } else {// 正常占位符 sbuf.append(strPattern, handledPosition, delimIndex); sbuf.append(StrUtil.utf8Str(argArray[argIndex])); - handledPosition = delimIndex + 2; + handledPosition = delimIndex + placeHolderLength; } } - // append the characters following the last {} pair. // 加入最后一个占位符后所有的字符 - sbuf.append(strPattern, handledPosition, strPattern.length()); + sbuf.append(strPattern, handledPosition, strPatternLength); return sbuf.toString(); } diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/StrFormatterTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/StrFormatterTest.java index 5803a6287..fd8ce5742 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/StrFormatterTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/StrFormatterTest.java @@ -6,19 +6,34 @@ import org.junit.Test; import cn.hutool.core.text.StrFormatter; public class StrFormatterTest { - + @Test - public void formatTest(){ + public void formatTest() { //通常使用 String result1 = StrFormatter.format("this is {} for {}", "a", "b"); Assert.assertEquals("this is a for b", result1); - + //转义{} String result2 = StrFormatter.format("this is \\{} for {}", "a", "b"); Assert.assertEquals("this is {} for a", result2); - + //转义\ String result3 = StrFormatter.format("this is \\\\{} for {}", "a", "b"); Assert.assertEquals("this is \\a for b", result3); } + + @Test + public void formatWithTest() { + //通常使用 + String result1 = StrFormatter.formatWith("this is ? for ?", "?", "a", "b"); + Assert.assertEquals("this is a for b", result1); + + //转义? + String result2 = StrFormatter.formatWith("this is \\? for ?", "?", "a", "b"); + Assert.assertEquals("this is ? for a", result2); + + //转义\ + String result3 = StrFormatter.formatWith("this is \\\\? for ?", "?", "a", "b"); + Assert.assertEquals("this is \\a for b", result3); + } }