根據模板提取變數資訊
阿新 • • 發佈:2018-11-07
問題來源:
最近公司要做簡訊中轉服務平臺,由於是第一次接觸這個業務,中間跳了不少坑,其中有一部分就是:上游通道需要配置資訊模板,介面中提供可變資訊即可;下游通道則是隻能提供完整資訊,無法提供可變資訊(吐槽一下:就是太LAN,不想弄而已),沒有辦法,只好由我們自己完成可變資訊的提取,然後將可變資訊以固定格式提交到上游通道,可變資訊後面統稱為變數資訊。
經過努力,完成了一個測試類,可以根據完整資訊內容和模板來自動提取出內容中的變數資訊,並可以根據完整資訊的長度來自動將模板分割成兩條或更多,以及對應條數的變數資訊,話不多說,直接上程式碼:
package com.hyfd.service; import java.util.ArrayList; import java.util.List; public class ArgsGet { // 滿足資訊分割條件的長度(這裡設定為滿100字元即進行分割) private static final int STR_SPLIT_MAX_LENGTH = 100; public static void main(String[] args) { String smsStr = ToDBC("成吉思汗的騎兵,***速度與二十世紀的裝甲部隊相當;北宋的床弩,射程達" + "一千五百米,與二十世紀的狙擊×××差不多;但這些仍不過是古代的騎兵與×××而已,不可能與" + "現代力量抗衡。基礎理論決定一切,未來史學派清楚地看到了這一點。而你們,卻被迴光返照的" + "低階技術矇住了眼睛。你們躺在現代文明的溫床中安於享樂,對即將到來的決定人類命運的終極" + "決戰完全沒有精神上的準備。"); getArgsList(smsStr); } /** * <h5>功能:獲取資訊拆分後的變數資訊</h5> * @param smsStr 完整資訊內容 */ private static List<String> getArgsList(String smsStr) { String ptTemplateAll = "#*#的騎兵,***速度與#*#世紀的裝甲部隊相當;#*#的#*#,射程達#*#米," + "與#*#世紀的#*#差不多;但這些仍不過是古代的#*#與#*#而已,不可能與#*#力量抗衡。#*#決" + "定一切,#*#清楚地看到了這一點。而你們,卻被迴光返照的#*#矇住了眼睛。你們躺在#*#的溫床" + "中安於#*#,對即將到來的決定人類命運的#*#完全沒有精神上的準備。"; String[] ptTemplate = ptTemplateAll.split("#\\*#"); System.out.println("完整資訊[" + smsStr + "]"); System.err.println("完整模板[" + ptTemplateAll + "]"); // 拆分資訊內容 List<String> smsList = smsSplit(smsStr, ptTemplate); // 根據資訊內容拆分模板 List<List<String>> templateSplit = templateSplist(smsList, ptTemplate); for (int i = 0; i < templateSplit.size(); i++) { System.out.println("第" + (i + 1) + "段拆分模板" + templateSplit.get(i) + ""); } List<String> argsList = new ArrayList<String>(); // 根據拆分後的資訊內容和模板獲取對應的變數資訊 for (int i = 0; i < smsList.size(); i++) { String tempSmsStr = smsList.get(i); List<String> templateSplist = templateSplit.get(i); for (String template : templateSplist) { if (!"".equals(template)) { tempSmsStr = tempSmsStr.replaceFirst(template, ","); } } if (tempSmsStr.endsWith(",")) { tempSmsStr = tempSmsStr.substring(0, tempSmsStr.length() - 1); } argsList.add(tempSmsStr); System.err.println("第" + (i + 1) + "段變數資訊[" + tempSmsStr + "]"); } return argsList; } /** * <h5>功能:拆分資訊內容</h5> * @param smsStr 完整資訊內容 * @param ptTemplate 陣列化的模板資訊 * @return */ private static List<String> smsSplit(String smsStr, String[] ptTemplate){ List<String> smsList = new ArrayList<String>(); StringBuffer sbf = new StringBuffer(); for (String template: ptTemplate) { if (!"".equals(template)) { // 一旦資訊內容長度超過100,則進行資訊拆分 if (sbf.length() > STR_SPLIT_MAX_LENGTH) { // System.out.println(sbf.toString()); smsList.add(sbf.toString()); sbf.setLength(0); } sbf.append(smsStr.substring(0, smsStr.indexOf(template) + template.length())); smsStr = smsStr.substring(smsStr.indexOf(template)+template.length()); } } smsList.add(sbf.toString()); return smsList; } /** * <h5>功能:根據資訊內容拆分模板</h5> * @param smsList 拆分後的資訊內容 * @param ptTemplate 模板資訊 * @return */ private static List<List<String>> templateSplist(List<String> smsList, String[] ptTemplate){ List<List<String>> templateList = new ArrayList<List<String>>(); for (String smsStr : smsList) { // System.out.println(smsStr); // 1.獲取資訊結束標識 String sbf = ""; for (String template : ptTemplate) { if (!"".equals(template)) { if (smsStr.endsWith(template)) { // System.out.println(template+"="+smsStr.indexOf(template)); sbf = template; } } } // 2.根據資訊標識,將資訊模板進行對應的拆分 List<String> tempList = new ArrayList<String>(); StringBuffer tempSbf = new StringBuffer(); for (int i = 0; i < ptTemplate.length; i++) { tempSbf.append(ptTemplate[i]); if (!"".equals(tempSbf.toString())) { tempList.add(tempSbf.toString()); if (sbf.equals(tempSbf.toString())) { ptTemplate[i] = ""; break; } else { ptTemplate[i] = ""; } } tempSbf.setLength(0); } templateList.add(tempList); // System.out.println(JSONObject.toJSONString(tempList)); // System.out.println("-----------------------------"); } return templateList; } /** * <h5>功能:全形轉半形</h5> * 這個主要是為了規範資訊內容,因此對全形資訊做了半形處理,不用的時候從引用的地方直接去掉即可 * @author zhangpj @date 2018年11月5日 * @param str * @return */ public static String ToDBC(String str) { char[] c = str.toCharArray(); for (int i = 0; i < c.length; i++) { // 全形空格為12288,半形空格為32 if (c[i] == 12288) { c[i] = (char) 32; continue; } // 其他字元半形(33-126)與全形(65281-65374)的對應關係是:均相差65248 if (c[i] > 65280 && c[i] < 65375) c[i] = (char) (c[i] - 65248); } return new String(c); } }
測試結果,可以看到模板分段並完美的獲取到了對應的變數資訊,效果如下
後記
由於趕時間沒有做優化,如果有不當之處,歡迎各位大神指教,謝謝!