Java代码
1. /*
2.  * 字符串"$ \"中的$与\字符互换位置
3.  */
4. public class SpecialCharReplace {
5.    public static void main(String[] args) {
6.        String str = "$ \\";
7.        /*
8.          * placeAll()中的特殊字符 $ 与 \
9.          *
10.          * 由于 $ 字符在作为替换内容时,是⼀个特殊字符,指反向引⽤前⾯的分组内容,所以把
11.          * 某字符替换成 $ 字符时,因该在前⾯加上转义字符 \。
12.          * \ 字符就不⽤说了,本⾝就是转义字符,但为什么在作为替换内容时要使⽤四个 \ 字符
13.          * ,这⾥⼜不是⽤在正则表达式⾥?这就是因为 \ 字符在作为替换内容⾥也是⼀个特殊字
14.          * 符,它⽤来将前⾯讲的 $ 字符进⾏转换的,所以也为特殊字符。以下是replaceAll的
15.          * 源码⽚断,从源码就可以看出 \$ 是两个特殊字符
16.          *
17.          * if (nextChar == '\\') {
18.          *      cursor++;
19.          *      nextChar = replacement.charAt(cursor);
20.          *      result.append(nextChar);
21.          *      cursor++;
22.          * } else if (nextChar == '$') {
23.          *      // Skip past $
24.          *      cursor++;
25.          *      ...
26.          * }else {
27.          *      result.append(nextChar);
28.          *      cursor++;
29.          * }
30.          */
31.        System.out.placeAll("\\$(\\W)\\\\", "\\\\$1\\$"));// \ $
32.    }
33.
34. }
/*
* 字符串"$ \"中的$与\字符互换位置
*/
public class SpecialCharReplace {
public static void main(String[] args) {
String str = "$ \\";
/
*
* placeAll()中的特殊字符 $ 与 \
*
* 由于 $ 字符在作为替换内容时,是⼀个特殊字符,指反向引⽤前⾯的分组内容,所以把
* 某字符替换成 $ 字符时,因该在前⾯加上转义字符 \。
* \ 字符就不⽤说了,本⾝就是转义字符,但为什么在作为替换内容时要使⽤四个 \ 字符
* ,这⾥⼜不是⽤在正则表达式⾥?这就是因为 \ 字符在作为替换内容⾥也是⼀个特殊字
* 符,它⽤来将前⾯讲的 $ 字符进⾏转换的,所以也为特殊字符。以下是replaceAll的
* 源码⽚断,从源码就可以看出 \$ 是两个特殊字符
*
* if (nextChar == '\\') {
*      cursor++;
*      nextChar = replacement.charAt(cursor);
*      result.append(nextChar);
*      cursor++;
* } else if (nextChar == '$') {
*      // Skip past $
*      cursor++;
*      ...
* }else {
*      result.append(nextChar);
*      cursor++;
* }
*/
System.out.placeAll("\\$(\\W)\\\\", "\\\\$1\\$"));// \ $
}
}
Matcher对象的appendReplacement典型应⽤与特殊字符&\的进⼀步分析
问题的提出
字符串模板:
String template="尊敬的客户${customerName}你好!本次消费⾦额${amount},您帐户${accountNumber}上的余额为${balance},欢迎下次光临!";
其中以 ${ 开始 } 结尾的为待替换的变量域。
数据存放于Map中,key为域名,value为域值。如:
Map--
customerName = 刘明
accountNumber = 888888888
balance = $1000000.00
amount = $1000.00
请编写函数:
public static String composeMessage(String template, Map data) throw Exception
实现将任意模板字符串中的变量域,按域名替换为data中的域值。
例如,上例替换结果为:
"尊敬的客户刘明你好!本次消费⾦额$1000.00,您帐户888888888上的余额为$1000000.00,欢迎下次光临!"
注:如果Map中不到域值,以空字符串""替换。
问题的解决
Java代码
1. public class RegexExam {
2.    public static void main(String args[]) {
3.        HashMap data = new HashMap();
4.        String template = "尊敬的客户${customerName}你好!本次消费⾦额${amount},"
5.                + "您帐户${accountNumber}上的余额为${balance},欢迎下次光临!";
6.        data.put("customerName", "刘明");
7.        data.put("accountNumber", "888888888");
8.        data.put("balance", "$1000000.00");
9.        data.put("amount", "$1000.00");
10.        try {
11.            System.out.println(composeMessage(template, data));
12.        } catch (Exception e) {
13.            e.printStackTrace();
14.        }
15.    }
16.
17.    public static String composeMessage(String template, Map data)
18.            throws Exception {
19.        String regex = "\\$\\{(.+?)\\}";
20.        Pattern pattern = Patternpile(regex);
21.        Matcher matcher = pattern.matcher(template);
22.        /*
23.          * sb⽤来存储替换过的内容,它会把多次处理过的字符串按源字符串序
24.          * 存储起来。
25.          */
26.        StringBuffer sb = new StringBuffer();
27.        while (matcher.find()) {
28.            String name = up(1);//键名
29.            String value = (String) (name);//键值
30.            if (value == null) {
31.                value = "";
replaceall()
32.            } else {
33.                /*
34.                  * 由于$出现在replacement中时,表⽰对捕获组的反向引⽤,所以要对上⾯替换内容
35.                  * 中的 $ 进⾏替换,让它们变成 "\$1000.00" 或 "\$1000000000.00" ,这样
36.                  * 在下⾯使⽤ matcher.appendReplacement(sb, value) 进⾏替换时就不会把
37.                  * $1 看成是对组的反向引⽤了,否则会使⽤⼦匹配项值amount 或 balance替换 $1
38.                  * ,最后会得到错误结果:
39.                  *
40.                  * 尊敬的客户刘明你好!本次消费⾦额amount000.00,您帐户888888888上的余额
41.                  * 为balance000000.00,欢迎下次光临!
42.                  *
43.                  * 要把 $ 替换成 \$ ,则要使⽤ \\\\\\& 来替换,因为⼀个 \ 要使⽤ \\\ 来进
44.                  * ⾏替换,⽽⼀个 $ 要使⽤ \\$ 来进⾏替换,因 \ 与  $ 在作为替换内容时都属于
45.                  * 特殊字符:$ 字符表⽰反向引⽤组,⽽ \ 字符⼜是⽤来转义 $ 字符的。
45.                  * 特殊字符:$ 字符表⽰反向引⽤组,⽽ \ 字符⼜是⽤来转义 $ 字符的。
46.                  */
47.                value = placeAll("\\$", "\\\\\\$");
48.                //System.out.println("value=" + value);
49.            }
50.            /*
51.              * 经过上⾯的替换操作,现在的 value 中含有 $ 特殊字符的内容被换成了"\$1000.00"
52.              * 或 "\$1000000000.00" 了,最后得到下正确的结果:
53.              *
54.              * 尊敬的客户刘明你好!本次消费⾦额$1000.00,您帐户888888888上的
55.              * 余额为$1000000.00,欢迎下次光临!
56.              *
57.              * 另外,我们在这⾥使⽤Matcher对象的appendReplacement()⽅法来进⾏替换操作,⽽
58.              * 不是使⽤String对象的replaceAll()或replaceFirst()⽅法来进⾏替换操作,因为
59.              * 它们都能只能进⾏⼀次性简单的替换操作,⽽且只能替换成⼀样的内容,⽽这⾥则是要求每
60.              * ⼀个匹配式的替换值都不同,所以就只能在循环⾥使⽤appendReplacement⽅式来进⾏逐
61.              * 个替换了。
62.              */
63.            matcher.appendReplacement(sb, value);
64.            System.out.println("sb = " + sb.toString());
65.        }
66.        //最后还得要把尾串接到已替换的内容后⾯去,这⾥尾串为“,欢迎下次光临!”
67.        matcher.appendTail(sb);
68.        String();
69.    }
70. }

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。