在学习调用第三方短信平台发送短信的时候,生成短信日志需要对发送的参数做提取和替换的处理。这就涉及到字符串的搜索和匹配以及替换。对调用第三方短信平台发短信有兴趣的可以参考我博文。
网易云通信 :https://blog.csdn.net/Henry_Lin_Wind/article/details/88190605
阿里大于:https://blog.csdn.net/Henry_Lin_Wind/article/details/88183486
需求描述:
1、假设客户端发来如下的请求参数,需要从参数列表中提取参数的属性,并相应的拼接到模板中
"time":"2019年03月08日 13:00","sstore_name":"阿里大于_Abc","amount":"8888.8","balance":"99999","sstore_mobile":"020-1592055"
2、模板内容如下(此模板在平台申请并获得模板ID)
消费提醒:你的手机号于${time}在${sstore_name}消费${amount}元。当前余额${balance}元。欢迎再次来店使用。本店联系方式:${sstore_mobile}。
3、拼接后的短信发送内容(实际发送中是发送请求参数给平台,匹配相应的模板ID,平台会自动拼接并提交给运营商发送短信),用于生成短信日志。
消费提醒:你的手机号于 2019年03月08日 13:00 在 阿里大于_Abc 消费 8888.8 元。当前余额 99999 元。欢迎再次来店使用。本店联系方式: 020-1592055 。
解决方法:
A: 字符串的处理有多种方式,最常用的就是 String 类自带的方法。常用的使用方法可以自行网上查找。接下来分享我使用String类的解决方案。
创建一个返回类型为数组的方法,作用是根据参数前后的特殊字符,依次提取字符串的参数属性并保存到数组中。
public static String[] stringGet(String head,String tail,String params) {
String array1[] =new String[10] ;
int n=0;
String subString="";
for (int i=0;i<params.length()-2;i++){
String r=params.substring(i, i+head.length());
if (r.equals(head)){
subString=params.substring(i+head.length(), params.length());
array1[n]=subString.substring(0,subString.indexOf(tail));
n++;
}
}
String array2[] =new String[n] ;
for(int i=0;i<n;i++){
array2[i] = array1[i];
}
return array2;
}
在主函数中调用该方法,通过该方法分别提取参数字符串的参数属性和模板的变量,生成两个数组。然后通过拼接和替换生成最终的短信内容。
public static void main(String[] args) throws Exception {
String params = "\"time\":\"2019年03月08日 13:00\",\"sstore_name\":\"阿里大于_Abc\",\"amount\":\"8888.8\",\"balance\":\"99999\",\"sstore_mobile\":\"020-1592055\"";
String[] paramArray = stringGet(":\"","\"",params);
for (String paramArr:paramArray) {
System.out.println(paramArr);
}
String temContent = "消费提醒:你的手机号于${time}在${sstore_name}消费${amount}元。当前余额${balance}元。欢迎再次来店使用。本店联系方式:${sstore_mobile}。";
String contentArray[] = stringGet("${","}",temContent);
for (String contentArr:contentArray) {
System.out.println(contentArr);
}
String smsLogContent = temContent ;
for(int i=0;i<paramArray.length;i++){
smsLogContent= smsLogContent.replace("${"+contentArray[i]+"}",paramArray[i]);
}
System.out.println(smsLogContent);
}
上述解决方案显得过于繁琐,可读性不强。这是因为String类功能有限,处理较复杂的文本时稍显不足。因此我们可以使用正则表达式来处理。正则表达式的语法课自行网上查找。
Sring类也可以用正则表达式,比如String[ ] split(String regex):指定正则表达式分隔符,返回一个字符串数组,但是功能有限且方法少。因此我们可以使用功能更加强大的 Pattern 类和 Matcher 类。
B: 使用Pattern.compile()方法来编译正则表达式并生成一个Pattern对象,然后把想要处理的字符串传入Pattern对象的matcher()方法,matcher()方法会生成一个Matcher对象。然后通过提取和替换,最终生成短信内容。
String params = "\"time\":\"2019年03月08日 13:00\",\"sstore_name\":\"阿里大于_Abc\",\"amount\":\"8888.8\",\"balance\":\"99999\",\"sstore_mobile\":\"020-1592055\"";
String temContent = "消费提醒:你的手机号于${time}在${sstore_name}消费${amount}元。当前余额${balance}元。欢迎再次来店使用。本店联系方式:${sstore_mobile}。";
Matcher m1 = Pattern.compile(":\"[^\"]+").matcher(params);//自字符串头开始, 以 :" 为起始,直到遇到 " ,以此类推直到字符串尾。
Matcher m2 = Pattern.compile("\\{[^}]+").matcher(temContent);// 自字符串头开始, 以 { 为起始,直到遇到 } ,以此类推直到字符串尾。
while(m1.find() && m2.find()){
temContent = temContent.replace(m2.group().substring(1),m1.group().substring(2));
}
System.out.println(temContent.replaceAll("\\$\\{|\\}"," "));
为方便观察,可以打印输出m1和m2
while(m1.find()) System.out.print(m1.group()+" | ");
while(m2.find()) System.out.print(m2.group()+" | ");
结果如下:
:"2019年03月08日 13:00 | :"阿里大于_Abc | :"8888.8 | :"99999 | :"020-1592055 |
{time | {sstore_name | {amount | {balance | {sstore_mobile |