From 8ce82953c5bd304644b4c11c35e37747012053c0 Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Tue, 16 Aug 2022 02:48:15 +0200 Subject: [PATCH] Named Placeholders in String Formatting (#12576) * Named Placeholders in String Formatting * assert notEqualTo --- .../namedformatting/NamedFormatter.java | 31 ++++++++++++ .../NamedFormatterUnitTest.java | 47 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/namedformatting/NamedFormatter.java create mode 100644 core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/namedformatting/NamedFormatterUnitTest.java diff --git a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/namedformatting/NamedFormatter.java b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/namedformatting/NamedFormatter.java new file mode 100644 index 0000000000..0fd0642f0e --- /dev/null +++ b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/namedformatting/NamedFormatter.java @@ -0,0 +1,31 @@ +package com.baeldung.namedformatting; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class NamedFormatter { + private NamedFormatter() {} + + public static String format(String template, Map parameters) { + StringBuilder newTemplate = new StringBuilder(template); + List valueList = new ArrayList<>(); + + Matcher matcher = Pattern.compile("[$][{](\\w+)}").matcher(template); + + while (matcher.find()) { + String key = matcher.group(1); + + String paramName = "${" + key + "}"; + int index = newTemplate.indexOf(paramName); + if (index != -1) { + newTemplate.replace(index, index + paramName.length(), "%s"); + valueList.add(parameters.get(key)); + } + } + + return String.format(newTemplate.toString(), valueList.toArray()); + } +} diff --git a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/namedformatting/NamedFormatterUnitTest.java b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/namedformatting/NamedFormatterUnitTest.java new file mode 100644 index 0000000000..843aaac0b5 --- /dev/null +++ b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/namedformatting/NamedFormatterUnitTest.java @@ -0,0 +1,47 @@ +package com.baeldung.namedformatting; + +import org.apache.commons.text.StrSubstitutor; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +class NamedFormatterUnitTest { + private static final String TEMPLATE = "Text: [${text}] Number: [${number}] Text again: [${text}]"; + + @Test + void givenTemplateWithNamedParam_whenCallingCommonsTextStrSubstitutor_shouldGetExpectedResult() { + Map params = new HashMap<>(); + params.put("text", "It's awesome!"); + params.put("number", 42); + String result = StrSubstitutor.replace(TEMPLATE, params, "${", "}"); + assertThat(result).isEqualTo("Text: [It's awesome!] Number: [42] Text again: [It's awesome!]"); + } + + @Test + void givenTemplateWithNamedParam_whenCallingCommonsTextStrSubstitutorWithParameterNames_shouldNotWorkAsExpected() { + Map params = new HashMap<>(); + params.put("text", "'${number}' is a placeholder."); + params.put("number", 42); + String result = StrSubstitutor.replace(TEMPLATE, params, "${", "}"); + + assertThat(result).isNotEqualTo("Text: ['${number}' is a placeholder.] Number: [42] Text again: ['${number}' is a placeholder.]"); + + assertThat(result).isEqualTo("Text: ['42' is a placeholder.] Number: [42] Text again: ['42' is a placeholder.]"); + } + + @Test + void givenTemplateWithNamedParam_whenCallingNamedFormatter_shouldGetExpectedResult() { + Map params = new HashMap<>(); + params.put("text", "It's awesome!"); + params.put("number", 42); + String result = NamedFormatter.format(TEMPLATE, params); + assertThat(result).isEqualTo("Text: [It's awesome!] Number: [42] Text again: [It's awesome!]"); + + params.put("text", "'${number}' is a placeholder."); + result = NamedFormatter.format(TEMPLATE, params); + assertThat(result).isEqualTo("Text: ['${number}' is a placeholder.] Number: [42] Text again: ['${number}' is a placeholder.]"); + } +}