开发者

Java equivalent of Python's format()

开发者_高级运维Here's two ways of doing string substitution:

name = "Tshepang"
"my name is {}".format(name)
"my name is " + name

How do I do something similar to the first method, using Java?


name = "Paŭlo";
MessageFormat f = new MessageFormat("my name is {0}");
f.format(new Object[]{name});

Or shorter:

MessageFormat.format("my name is {0}", name);


String s = String.format("something %s","name");


Underscore-java has a format() static method. Live example

import com.github.underscore.Underscore;

public class Main {
    public static void main(String[] args) {
        String name = "Tshepang";
        String formatted = Underscore.format("my name is {}", name);
        // my name is Tshepang
    }
}


You can try this

package template.fstyle;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static java.util.Objects.nonNull;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class FStyleFinal {
    private static final String PLACEHOLDERS_KEY = "placeholders";
    private static final String VARIABLE_NAMES_KEY = "variableNames";
    private static final String PLACEHOLDER_PREFIX = "{{";
    private static final String PLACEHOLDER_SUFFIX = "}}";
    private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\{\\{\\s*([\\S]+)\\s*}}");

    private static Map<String, List<String>> toPlaceholdersAndVariableNames(String rawTemplate) {
        List<String> placeholders = newArrayList();
        List<String> variableNames = newArrayList();

        Matcher matcher = PLACEHOLDER_PATTERN.matcher(rawTemplate);
        while (matcher.find()) {
            for (int j = 0; j <= matcher.groupCount(); j++) {
                String s = matcher.group(j);
                if (StringUtils.startsWith(s, PLACEHOLDER_PREFIX) && StringUtils.endsWith(s, PLACEHOLDER_SUFFIX)) {
                    placeholders.add(s);
                } else if (!StringUtils.startsWith(s, PLACEHOLDER_PREFIX) && !StringUtils.endsWith(s, PLACEHOLDER_SUFFIX)) {
                    variableNames.add(s);
                }
            }
        }
        checkArgument(CollectionUtils.size(placeholders) == CollectionUtils.size(variableNames), "template engine error");

        Map<String, List<String>> map = newHashMap();
        map.put(PLACEHOLDERS_KEY, placeholders);
        map.put(VARIABLE_NAMES_KEY, variableNames);
        return map;
    }

    private static String toJavaTemplate(String rawTemplate, List<String> placeholders) {
        String javaTemplate = rawTemplate;
        for (String placeholder : placeholders) {
            javaTemplate = StringUtils.replaceOnce(javaTemplate, placeholder, "%s");
        }
        return javaTemplate;
    }

    private static Object[] toJavaTemplateRenderValues(Map<String, String> context, List<String> variableNames, boolean allowNull) {
        return variableNames.stream().map(name -> {
            String value = context.get(name);
            if (!allowNull) {
                checkArgument(nonNull(value), name + " should not be null");
            }
            return value;
        }).toArray();
    }

    private static Map<String, String> fromBeanToMap(Object bean, List<String> variableNames) {
        return variableNames.stream().distinct().map(name -> {
            String value = null;
            try {
                value = BeanUtils.getProperty(bean, name);
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                log.debug("fromBeanToMap error", e);
            }
            return Pair.of(name, value);
        }).filter(p -> nonNull(p.getRight())).collect(Collectors.toMap(Pair::getLeft, Pair::getRight));
    }

    public static String render(String rawTemplate, Map<String, String> context, boolean allowNull) {
        Map<String, List<String>> templateMeta = toPlaceholdersAndVariableNames(rawTemplate);
        List<String> placeholders = templateMeta.get(PLACEHOLDERS_KEY);
        List<String> variableNames = templateMeta.get(VARIABLE_NAMES_KEY);
        // transform template to java style template
        String javaTemplate = toJavaTemplate(rawTemplate, placeholders);
        Object[] renderValues = toJavaTemplateRenderValues(context, variableNames, allowNull);
        return String.format(javaTemplate, renderValues);
    }

    public static String render(String rawTemplate, Object bean, boolean allowNull) {
        Map<String, List<String>> templateMeta = toPlaceholdersAndVariableNames(rawTemplate);
        List<String> variableNames = templateMeta.get(VARIABLE_NAMES_KEY);
        Map<String, String> mapContext = fromBeanToMap(bean, variableNames);
        return render(rawTemplate, mapContext, allowNull);
    }

    public static void main(String[] args) {
        String template = "hello, my name is {{ name }}, and I am  {{age}} years old, a null value {{ not_exists }}";
        Map<String, String> context = newHashMap();
        context.put("name", "felix");
        context.put("age", "18");
        String s = render(template, context, true);
        log.info("{}", s);

        try {
            render(template, context, false);
        } catch (IllegalArgumentException e) {
            log.error("error", e);
        }
    }
}

Sample output:

[main] INFO template.fstyle.FStyleFinal - hello, my name is felix, and I am  18 years old, a null value null
[main] ERROR template.fstyle.FStyleFinal - error
java.lang.IllegalArgumentException: not_exists should not be null
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:142)
    at template.fstyle.FStyleFinal.lambda$toJavaTemplateRenderValues$0(FStyleFinal.java:69)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:545)
    at java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
    at java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:438)
    at java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:444)
    at template.fstyle.FStyleFinal.toJavaTemplateRenderValues(FStyleFinal.java:72)
    at template.fstyle.FStyleFinal.render(FStyleFinal.java:93)
    at template.fstyle.FStyleFinal.main(FStyleFinal.java:113)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜