/**
* @param temp 尊敬的${name},您正在进行${action}操作
* @param msg 尊敬的张三,您正在进行找回密码操作
* @return
*/
private static Map<String, String> getParamMap(String temp, String msg) {
// 尊敬的\$\{(.*?)},您正在进行\$\{(.*?)}操作
String template1 = temp.replaceAll("\\$\\{(.*?)}", "\\\\\\$\\\\{(.*?)}");
// 尊敬的(.*?),您正在进行(.*?)操作
String template2 = temp.replaceAll("\\$\\{(.*?)}", "(.*?)");
// [name, action]
List<String> list1 = new ArrayList<>();
// [张三, 找回密码]
List<String> list2 = new ArrayList<>();
Map<String, String> map = new HashMap<>();
Pattern p1 = Pattern.compile(template1);
Matcher m1 = p1.matcher(temp);
if (m1.find()) {
for (int i = 1; i <= m1.groupCount(); i++) {
list1.add(m1.group(i));
}
}
Pattern p2 = Pattern.compile(template2);
Matcher m2 = p2.matcher(msg);
if (m2.find()) {
for (int i = 1; i <= m2.groupCount(); i++) {
list2.add(m2.group(i));
}
}
for (int i = 0; i < list1.size(); i++) {
map.put(list1.get(i), list2.get(i));
}
return map;
}
@Deprecated
private static Map<String, String> getParamMapOld(String template, String msg) {
if (template == null || msg == null) {
return null;
}
StringBuilder sbTem = new StringBuilder(template);
StringBuilder sb = new StringBuilder(msg);
Map<String, String> map = new HashMap<>();
boolean isFirst = true;
while (true) {
int startT = sbTem.indexOf("${");
if (startT == -1) {
break;
}
if(isFirst){
isFirst = false;
if(startT>0){
String beforeT = template.substring(0,startT);
if(msg.indexOf(beforeT)!=0){
throw new RuntimeException("信息与模板格式不匹配!");
}
}
}
int endT = sbTem.indexOf("}");
if(endT==-1){
break;
}
String afterT = sbTem.substring(endT + 1);
int next = afterT.indexOf("${");
int end;
if (next == -1 || afterT.length() < 1) {
//如果之后没有$了则取到最后
end = sb.length()-(sbTem.length() - endT-1);
} else {
String after = afterT.substring(0, next);
end = sb.indexOf(after);
if (end == -1) {
throw new MessageCenterException("信息与模板格式不匹配!");
}
}
//截取${}中的字段
String subT = sbTem.substring(startT + 2, endT);
String sub = sb.substring(startT, end);
map.put(subT, sub);
sbTem = new StringBuilder(sbTem.substring(endT + 1));
sb = new StringBuilder(sb.substring(end));
}
return map;
}
public static void main(String[] args) {
String template = "${test}尊敬的${name},您正在进行${asdf}操作,验证码:${code},请在${time}之内操作${32323}分";
String msg = "TEST尊敬的张三,您正在进行找回密码操作,验证码:asdf,请在5分钟之内操作9995998分";
log.info("startTime"+new Date());
Map<String, String> map = new HashMap<>();
for(int i=0;i<99999999;i++){
map= getParamMap(template, msg);
}
for (String key : map.keySet()) {
System.out.println(key + " : " + map.get(key));
}
log.info("endTime"+new Date());
log.info("***********");
log.info("startTime"+new Date());
Map<String, String> mapOld = new HashMap<>();
for(int i=0;i<99999999;i++){
mapOld= getParamMapOld(template, msg);
}
for (String key : mapOld.keySet()) {
System.out.println(key + " : " + mapOld.get(key));
}
log.info("endTime"+new Date());
}
如上,是从短信中取出系统添加的参数。
分别采用了正则,和手动撸两种方式。
16:58:31.901 [main] INFO com.yunzainfo.cloud.message.center.phone.DayuPhoneUtil - startTimeThu Sep 19 16:58:31 CST 2019
code : asdf
32323 : 9995998
test : TEST
name : 张三
asdf : 找回密码
time : 5分钟
16:59:31.102 [main] INFO com.yunzainfo.cloud.message.center.phone.DayuPhoneUtil - endTimeThu Sep 19 16:59:31 CST 2019
16:59:31.102 [main] INFO com.yunzainfo.cloud.message.center.phone.DayuPhoneUtil - ***********
16:59:31.102 [main] INFO com.yunzainfo.cloud.message.center.phone.DayuPhoneUtil - startTimeThu Sep 19 16:59:31 CST 2019
code : asdf
32323 : 9995998
test : TEST
name : 张三
asdf : 找回密码
time : 5分钟
16:59:42.305 [main] INFO com.yunzainfo.cloud.message.center.phone.DayuPhoneUtil - endTimeThu Sep 19 16:59:42 CST 2019
可以看到正则用了整整一分钟,手动撸只用了11秒。(而且笔者函数只是随手写的没有优化)
所以如果对性能有要求,还是要手撸。
不过正则写起来是真的简单,真香。