1. 程式人生 > >根據模板提取變量信息

根據模板提取變量信息

app 完美 pla 精神 提交 由於 基礎 mage ace

問題來源:
  最近公司要做短信中轉服務平臺,由於是第一次接觸這個業務,中間跳了不少坑,其中有一部分就是:上遊通道需要配置信息模板,接口中提供可變信息即可;下遊通道則是只能提供完整信息,無法提供可變信息(吐槽一下:就是太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);
    }
}

測試結果,可以看到模板分段並完美的獲取到了對應的變量信息,效果如下

技術分享圖片

後記
  由於趕時間沒有做優化,如果有不當之處,歡迎各位大神指教,謝謝!

根據模板提取變量信息