Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何用SimpleDataFormat模式替换字符串中的占位符_Java_Apache Commons_Spring El - Fatal编程技术网

Java 如何用SimpleDataFormat模式替换字符串中的占位符

Java 如何用SimpleDataFormat模式替换字符串中的占位符,java,apache-commons,spring-el,Java,Apache Commons,Spring El,在这样一个给定的字符串中 ".../uploads/${customer}/${dateTime('yyyyMMdd')}/report.pdf" 我需要更换customer和yyyyMMdd时间戳 要替换customer占位符,我可以使用apachecommons中的StrSubstitutor。但是如何替换SimpleDataFormat?我们在Spring环境中运行,所以Spring EL是否是一个选项 占位符的标记不是固定的,如果另一个库需要语法更改,也可以 这个小测试显示了问题: S

在这样一个给定的字符串中

".../uploads/${customer}/${dateTime('yyyyMMdd')}/report.pdf"
我需要更换
customer
yyyyMMdd
时间戳

要替换
customer
占位符,我可以使用apachecommons中的
StrSubstitutor
。但是如何替换
SimpleDataFormat
?我们在Spring环境中运行,所以
Spring EL
是否是一个选项

占位符的标记不是固定的,如果另一个库需要语法更改,也可以

这个小测试显示了问题:

SimpleDateFormat            formatter   = new SimpleDateFormat("yyyyMMdd");

String                      template    = ".../uploads/${customer}/${dateTime('yyyyMMdd')}/report.pdf";

@Test
public void shouldResolvePlaceholder()
{
    final Map<String, String> model = new HashMap<String, String>();
    model.put("customer", "Mr. Foobar");

    final String filledTemplate = StrSubstitutor.replace(this.template, model);

    assertEquals(".../uploads/Mr. Foobar/" + this.formatter.format(new Date()) + "/report.pdf", filledTemplate);
}
SimpleDataFormat格式化程序=新的SimpleDataFormat(“yyyyMMdd”);
String template=“…/uploads/${customer}/${dateTime('yyyyymmdd')}/report.pdf”;
@试验
public void shouldResolvePlaceholder()
{
最终映射模型=新HashMap();
模型出售(“客户”、“福巴先生”);
最终字符串filledTemplate=StrSubstitutor.replace(this.template,model);
assertEquals(“…/uploads/Mr.Foobar/”+this.formatter.format(new Date())+“/report.pdf”,filledTemplate);
}
为什么不改为使用

或与


正如NilsH所建议的,MessageFormat在这方面非常好。要使用命名变量,可以将MessageFormat隐藏在类后面:

public class FormattedStrSubstitutor {
    public static String formatReplace(Object source, Map<String, String> valueMap) {
        for (Map.Entry<String, String> entry : valueMap.entrySet()) {   
            String val = entry.getValue();
            if (isPlaceholder(val)) {
                val = getPlaceholderValue(val);
                String newValue = reformat(val);

                entry.setValue(newValue);
            }
        }

        return new StrSubstitutor(valueMap).replace(source);
    }

    private static boolean isPlaceholder(String isPlaceholder) {
        return isPlaceholder.startsWith("${");
    }

    private static String getPlaceholderValue(String val) {
        return val.substring(2, val.length()-1);
    }

    private static String reformat(String format) {
        String result = MessageFormat.format("{0,date," + format + "}", new Date());

        return result;
    }
}
您的测试用例与您的问题类似(占位符中的小变化):

SimpleDataFormat格式化程序=新的SimpleDataFormat(“yyyyMMdd”);
String template=“…/uploads/${customer}/${date,yyyyymmdd}/report.pdf”;
@试验
public void shouldResolvePlaceholder(){
最终映射模型=新HashMap();
模型出售(“客户”、“福巴先生”);
最后一个字符串filledTemplate=FormattedStrSubstitutor.replace(this.template,
模型);
资产质量(
“../uploads/Mr.Foobar/”+this.formatter.format(new Date())
+“/report.pdf”,填写模板);
}

与以前相同的限制;没有泛型,并修复占位符的前缀和后缀。

看起来就这么简单

static final Pattern DOLLARS = Pattern.compile("\\$\\{([^}]+)}");

public static String resolve(String string, Map<String,String> config) {
    StringBuilder builder = new StringBuilder();
    Matcher matcher = DOLLARS.matcher(string);
    int start = 0;
    while (matcher.find(start)) {
        builder.append(string.substring(start, matcher.start()));
        String property = matcher.group(1);
        String value = config.get(property);
        builder.append(value);
        start = matcher.end();
    }
    builder.append(string.substring(start));
    return builder.toString();
}
static final Pattern$s=Pattern.compile(“\\$\\{([^}]+)}”);
公共静态字符串解析(字符串、映射配置){
StringBuilder=新的StringBuilder();
Matcher Matcher=美元。Matcher(字符串);
int start=0;
while(匹配器查找(开始)){
append(string.substring(start,matcher.start());
字符串属性=matcher.group(1);
String value=config.get(属性);
附加(值);
start=matcher.end();
}
append(string.substring(start));
返回builder.toString();
}

<代码>,日期部分是否始终是目录结构中的最后一个文件夹?不,在其他一些报告中,它位于中间。或者在文件名中。这只是一个例子,我喜欢命名变量的方式。因为字符串来自另一个模块。他们不知道我用的是什么。使用
MessageFormat
我需要传达索引0=客户,1=当前日期,2=。。。。嗯……格式化不是一个实现细节吗?它是如何“暴露”给你的客户的?它不只是一个带有类型化参数的方法调用吗?
public class FormattedStrSubstitutor {
    public static String formatReplace(Object source, Map<String, String> valueMap) {
        for (Map.Entry<String, String> entry : valueMap.entrySet()) {   
            String val = entry.getValue();
            if (isPlaceholder(val)) {
                val = getPlaceholderValue(val);
                String newValue = reformat(val);

                entry.setValue(newValue);
            }
        }

        return new StrSubstitutor(valueMap).replace(source);
    }

    private static boolean isPlaceholder(String isPlaceholder) {
        return isPlaceholder.startsWith("${");
    }

    private static String getPlaceholderValue(String val) {
        return val.substring(2, val.length()-1);
    }

    private static String reformat(String format) {
        String result = MessageFormat.format("{0,date," + format + "}", new Date());

        return result;
    }
}
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");

String template = ".../uploads/${customer}/${dateTime}/report.pdf";

@Test
public void shouldResolvePlaceholder() {
    final Map<String, String> model = new HashMap<String, String>();
    model.put("customer", "Mr. Foobar");
    model.put("dateTime", "${yyyyMMdd}");

    final String filledTemplate = FormattedStrSubstitutor.formatReplace(this.template,
        model);

    assertEquals(".../uploads/Mr. Foobar/" + this.formatter.format(new Date())
        + "/report.pdf", filledTemplate);
}
public static String replace(Object source,
        Map<String, String> valueMap) {

    String staticResolved = new StrSubstitutor(valueMap).replace(source);

    Pattern p = Pattern.compile("(\\$\\{date)(.*?)(\\})");
    Matcher m = p.matcher(staticResolved);

    String dynamicResolved = staticResolved;
    while (m.find()) {
        String result = MessageFormat.format("{0,date" + m.group(2) + "}",
                new Date());

        dynamicResolved = dynamicResolved.replace(m.group(), result);
    }

    return dynamicResolved;
}
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");

String template = ".../uploads/${customer}/${date,yyyyMMdd}/report.pdf";

@Test
public void shouldResolvePlaceholder() {
    final Map<String, String> model = new HashMap<String, String>();
    model.put("customer", "Mr. Foobar");

    final String filledTemplate =  FormattedStrSubstitutor.replace(this.template,
            model);

    assertEquals(
            ".../uploads/Mr. Foobar/" + this.formatter.format(new Date())
                    + "/report.pdf", filledTemplate);
}
static final Pattern DOLLARS = Pattern.compile("\\$\\{([^}]+)}");

public static String resolve(String string, Map<String,String> config) {
    StringBuilder builder = new StringBuilder();
    Matcher matcher = DOLLARS.matcher(string);
    int start = 0;
    while (matcher.find(start)) {
        builder.append(string.substring(start, matcher.start()));
        String property = matcher.group(1);
        String value = config.get(property);
        builder.append(value);
        start = matcher.end();
    }
    builder.append(string.substring(start));
    return builder.toString();
}