字符串的参数替换

今天CSDN上碰见一位朋友想要完成,替换字符串中的参数为某个变量值。

记得以前开发时就遇到过这样的问题。

比如:我们给用户群发有用户针对性的短信时,就会遇到这种情况。

我们一般会先出一个模板句子:

      “尊敬的XXX先生,欢迎使用我们公司为您提供的XXX业务,资费XXX元已经扣除。”

计算机实现的时候,就要生成一个模板字符串:

      String modelStr = "尊敬的${customer}先生,欢迎使用我们公司为您提供的${service}业务,资费${price}已经扣除。"

然后想办法将里面用“${”和“}”括起来的内容根据具体情况进行替换。

为了通用起见,我们会将这三个参数以及要替换的变量做成Map对象进行存储,每个用户一个Map对象。

这样的话,所有用户只需创建一个模板字符串的对象,然后不停的调用convert(Map)方法,就能得到各自的具体的字符串了。

 

找了半天,终于在以前的代码中翻出来了,里面我又做了点更改。呵呵,发到Blog大家互相交流一下。

还要注意,我写的这个类不是线程安全的。


晒晒代码如下:

package houlei.java.util;

import java.util.Map;
import java.lang.StringBuilder;

/**
 * <strong>可替换参数变量的字符串类。</strong> 参数的形式为:${参数}<p/>
 * 例如:字符串 "This is a ${SomeThing}." 可替换的部分是:${SomeThing}。其中,SomeThing即为参数。<br/>
 * 如果要将${SomeThing}替换为字符串"Demo"(也就是说替换后的字符串是:"This is a Demo."),
 * 我们可以将SomeThing和Demo组成键值对放入Map中进行转换。<p/>
 * 代码示例:<br/>
 * <pre>{@code
 * String demoStr = "This is a ${SomeThing}.";
 * DynamicString ds = new DynamicString(demoStr);
 * Map<String,String> param = new java.util.HashMap<String,String>(4);
 * param.put("SomeThing", "Demo");
 * System.out.println(ds.convert(param));
 * }</pre>
 * <strong>注意:反斜杠'\'是转义字符,活用可处理常见问题。</strong>
 * <P>该类创建于 2010-3-3 上午01:06:26
 * @version 1.0.0
 * @author 侯磊
 */
public class DynamicString {
    private String dynStr;
    private DynamicPattern header;
    private DynamicPattern tail;

    static abstract class DynamicPattern {
        DynamicPattern next;

        public abstract Object subConvert(Map<String, ?> pattern);
    }

    static class StringPattern extends DynamicPattern {
        private String pattern;

        public StringPattern(StringBuilder buff, int start, int end) {
            this.pattern = buff.substring(start, end);
        }

        @Override
        public Object subConvert(Map<String, ? extends Object> map) {
            return pattern;
        }
    }

    static class MappedPattern extends DynamicPattern {
        private String key;

        public MappedPattern(StringBuilder buff, int start, int end) {
            this.key = buff.substring(start, end);
        }

        @Override
        public Object subConvert(Map<String, ? extends Object> param) {
            if (param.get(key) == null) {
                throw new IllegalArgumentException("所传入的Map中,不含有参数:" + key);
            }
            return param.get(key);
        }
    }

    /**
     * 可替换参数变量的字符串类。该类适用于多个参数的情况。
     * @param dynStr 模板字符串。
     */
    public DynamicString(String dynStr) {
        this.dynStr = dynStr;
        init();
    }

    /**
     * 生成中间模板,转义字符也要考虑在内。
     */
    private void init() {
        header = tail = null;
        StringBuilder buff = new StringBuilder(dynStr);
        int start = 0, ptr = 0;
        boolean noMatching = true;
        for (ptr = start; ptr < buff.length(); ptr++) {
            if (buff.charAt(ptr) == '$' && buff.charAt(ptr + 1) == '{') {
                if (ptr > 0 && buff.charAt(ptr - 1) == '\\') {
                    buff.deleteCharAt(ptr-- - 1);
                    if (ptr > 1 && buff.charAt(ptr - 1) == '\\' && buff.charAt(ptr - 2) == '\\') {
                        buff.deleteCharAt(ptr-- - 1);
                        continue;
                    }
                    if (!(ptr > 0 && buff.charAt(ptr - 1) == '\\')) continue;
                }
                noMatching = false;
                StringPattern sp = new StringPattern(buff, start, ptr);
                appendPattern(sp);
                start = ptr + 2;
                for (ptr += 2; ptr < buff.length(); ptr++) {
                    if (buff.charAt(ptr) == '}') {
                        if (buff.charAt(ptr - 1) == '\\') {
                            buff.deleteCharAt(ptr-- - 1);
                            if (buff.charAt(ptr - 1) != '\\') continue;
                        }
                        MappedPattern mp = new MappedPattern(buff, start, ptr);
                        appendPattern(mp);
                        noMatching = true;
                        start = ++ptr;
                        break;
                    }
                }
            }
        }
        if (noMatching && ptr <= buff.length()) appendPattern(new StringPattern(buff, start, ptr));
    }

    private DynamicString appendPattern(DynamicPattern pattern) {
        if (header == null) {
            header = pattern;
            tail = header;
        } else {
            tail.next = pattern;
            tail = pattern;
        }
        return this;
    }

    /**
     * 传入参数变量,得到替换后的结果。
     * @param param 将替换的参数及变量以键值对的形式存放到Map对象中。
     * @return 返回替换回的结果。
     * @exception IllegalArgumentException 当待替换的参数不在Map对象中时,抛出该异常。
     */
    public String convert(Map<String, ? extends Object> param) {
        if (header == null) return null;
        DynamicPattern ptr = header;
        StringBuilder sb = new StringBuilder();
        while (ptr != null) {
            sb.append(ptr.subConvert(param));
            ptr = ptr.next;
        }
        return sb.toString();
    }

    /**
     * @see #convert(Map)
     */
    public String convert(String key, String value) {
        Map<String, String> param = new java.util.HashMap<String, String>(2);
        param.put(key, value);
        return convert(param);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值