媒资融合

挑水做饭 2020年05月29日 121次浏览

项目需要爬取全网的媒资内容并将相同的媒资融合在一起,例如腾讯有天龙八部,芒果也有天龙八部,这样就会生成一个天龙八部的融合合集,下面关联不同cp的天龙八部合集,用户在检索媒资的时候,会首先出现融合合集,然后可以选择不同cp合集,合集的名称有很多种,如天龙八部第一部、天龙八部第1部等,如何将其归类到同一个融合合集,我们很容易的能想到通过正则来处理合集名称做兼容处理,正则处理逻辑如下:

package com.mgtv.merge.utils;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegUtil {
    private static Logger LOGGER = LoggerFactory.getLogger(RegUtil.class);

    /**
     * 融合规则兼容逻辑替换
     * <p>
     * 合集名称兼容:需带字符兼容逻辑,如:2=Ⅱ=二=第2季=第2季=第二部、粤语=粤语版、空格、逗号、破折号等;
     *
     * @param s 带处理字符串
     * @return 返回处理后的字符串
     */
    public static String relateWordReplace(String s) {
        if (StringUtils.isEmpty(s)) {
            return s;
        }

        String tmp = s;

        s = s.trim();

        //央视春节联欢晚会 2016 =>2016央视春节联欢晚会
        s = mReverseNumbers(s);
        //萌学园 第4季 时空战役 => 萌学园 时空战役 第4季
        s = reverseByWhiteSpace(s);
        //去除特殊符号 \s()()<>《》【】\[\]\{\}‘’“”'"::,,;;.。`/、|\-=的之——
        s = removeIgnoreChars(s);
        //粤语版 => 粤语
        s = replaceLanguage(s);
        //英文版 => 英语版
        s = mReplaceWen(s);
        //天眼 Ⅱ => 天眼 第2部
        s = mReplaceNumbers(s);
        //天眼 第四季 => 天眼4
        s = mReplaceJI(s);

        LOGGER.info(String.format("relateWordReplace方法,转换前:%s 转换后:%s", tmp, s));

        //如果去除完后成了空字符串,直接返回传过来的值
        if (StringUtils.isEmpty(s)) {
            s = tmp;
        }

        return s.toLowerCase();
    }

    /**
     * 央视春节联欢晚会 2016 =>2016央视春节联欢晚会
     *
     * @param s
     * @return
     */
    private static String mReverseNumbers(String s) {
        String pattern = "^(.*)\\s*([0-9]{4})$";
        Matcher m = Pattern.compile(pattern).matcher(s);
        while (m.find()) {
            return String.format("%s %s", m.group(2).trim(), m.group(1).trim());
        }

        return s;
    }

    /**
     * 将数字转成统一格式的数字
     * 天眼 Ⅱ => 天眼 2
     *
     * @param s
     * @return
     */
    private static String mReplaceNumbers(String s) {
        String pattern = "^(.*)([0-9]|[一二三四五六七八九十]|[ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ])$";
        Matcher m = Pattern.compile(pattern).matcher(s);
        while (m.find()) {
            String num = changNum1(m.group(2));
            num = changNum2(num);
            return String.format("%s%s", m.group(1), num);
        }
        return s;
    }

    /**
     * 数字转换  二 ---> 2
     *
     * @param num
     * @return
     */
    private static String changNum1(String num) {
        String revNum = num;
        switch (num) {
            case "一":
                revNum = "1";
                break;
            case "二":
                revNum = "2";
                break;
            case "三":
                revNum = "3";
                break;
            case "四":
                revNum = "4";
                break;
            case "五":
                revNum = "5";
                break;
            case "六":
                revNum = "6";
                break;
            case "七":
                revNum = "7";
                break;
            case "八":
                revNum = "8";
                break;
            case "九":
                revNum = "9";
                break;
            case "十":
                revNum = "10";
                break;
            default:
                revNum = num;

        }
        return revNum;
    }

    /**
     * 数字转换  Ⅱ ---> 2
     *
     * @param num
     * @return
     */
    private static String changNum2(String num) {
        String revNum = num;
        switch (num) {
            case "Ⅰ":
                revNum = "1";
                break;
            case "Ⅱ":
                revNum = "2";
                break;
            case "Ⅲ":
                revNum = "3";
                break;
            case "Ⅳ":
                revNum = "4";
                break;
            case "Ⅴ":
                revNum = "5";
                break;
            case "Ⅵ":
                revNum = "6";
                break;
            case "Ⅶ":
                revNum = "7";
                break;
            case "Ⅷ":
                revNum = "8";
                break;
            case "Ⅸ":
                revNum = "9";
                break;
            case "Ⅹ":
                revNum = "10";
                break;
            default:
                revNum = num;

        }
        return revNum;
    }

    /**
     * 天眼 第四季 => 天眼 第4部
     * 天眼 第Ⅱ季 => 天眼 第2部
     *
     * @param s
     * @return
     */
    private static String mReplaceJI(String s) {
        String pattern = "^(.*第)([0-9]{1,2}|[一二三四五六七八九十]{1,3})";
        Matcher m = Pattern.compile(pattern).matcher(s);
        while (m.find()) {
            String num = m.group(2);
            String revNum = changNum1(num);
            revNum = changNum2(revNum);
            return s.replace("季", "部")
                    .replace(num, revNum)
                    .replace("第" + revNum, revNum)
                    .replace(revNum + "部", revNum);
        }
        return s;
    }

    /**
     * 英文版 => 英语版
     *
     * @param s
     * @return
     */
    private static String mReplaceWen(String s) {
        String pattern = "^.*(英|日|韩)文版$";
        Matcher m = Pattern.compile(pattern).matcher(s);
        while (m.find()) {
            return m.group(0).replace("文", "语");
        }
        return s;
    }

    /**
     * 萌学园 第4季 时空战役 => 萌学园 时空战役 第4季
     *
     * @param s
     * @return
     */
    private static String reverseByWhiteSpace(String s) {
        String pattern = "^(\\S*)\\s+(第([0-9]{1,2}|[一二三四五六七八九十]{1,3})[季部])\\s+(\\S*)$";
        Matcher m = Pattern.compile(pattern).matcher(s);
        while (m.find()) {
            return String.format("%s %s %s", m.group(1), m.group(4), m.group(2));
        }
        return s;
    }

    /**
     * 粤语版 => 粤语
     *
     * @param s
     * @return
     */
    private static String replaceLanguage(String s) {
        String pattern = "^.*粤语版$";
        Matcher m = Pattern.compile(pattern).matcher(s);
        while (m.find()) {
            return m.group(0).replace("粤语版", "粤语");
        }
        return s;
    }

    private static void print(Matcher m) {
        for (int i = 0; i <= m.groupCount(); i++) {
            System.out.println(String.format("%s %s", i, m.group(i)));
        }
    }

    /**
     * 去除后缀如:2=Ⅱ=二
     *
     * @param s
     * @return
     */
    private static String removeAllNum(String s) {
        s = s.replaceAll("\\d+", "");
        return s;
    }

    /**
     * 去除后缀如:第2季=第二季=第二部
     *
     * @param s
     * @return
     */
    private static String removeLastSeries(String s) {
        String pattern = "^(.*)第([0-9]{1,2}|[一二三四五六七八九十]{1,3})(季|部)";
        Matcher m = Pattern.compile(pattern).matcher(s);
        while (m.find()) {
//            print(m);
            s = m.group(1);
        }
        return s;
    }

    /**
     * 去除后缀如:粤语版 粤语
     *
     * @param s
     * @return
     */
    private static String removeLastLangage(String s) {
        String pattern = "(^.*)粤语版?$";
        Matcher m = Pattern.compile(pattern).matcher(s);
        while (m.find()) {
            s = m.group(1);
        }
        return s;
    }

    /**
     * 去除后缀如:(英|日|韩)文版 (英|日|韩)语版
     *
     * @param s
     * @return
     */
    private static String removeLastWen(String s) {
        String pattern = "(^.*)(英|日|韩)(文|语)版$";
        Matcher m = Pattern.compile(pattern).matcher(s);
        while (m.find()) {
            s = m.group(1);
        }
        return s;
    }

    /**
     * 删除掉匹配上的特殊字符
     *
     * @param s
     * @return
     */
    private static String removeIgnoreChars(String s) {
        String pattern = "[\\s()()<>《》【】\\[\\]\\{\\}‘’“”'\"::,,;;.。`/、|\\-=的之——]";
        Matcher m = Pattern.compile(pattern).matcher(s);
        while (m.find()) {
//            print(m);
            s = m.replaceAll("");
        }
        return s;
    }

    /**
     * 去除后缀特殊字符串
     *
     * @param s
     * @return
     */
    public static String removeCpNameLastString(String s) {
        String tmp = s;
        if (StringUtils.isEmpty(s)) {
            return s;
        }

        //去掉特殊字符
        s = removeIgnoreChars(s);
        //去除后缀如:粤语版 粤语
        s = removeLastLangage(s).trim();
        //去除字符串中包含的数字
        s = removeAllNum(s).trim();
        //去除后缀如:第2季=第二季=第二部
        s = removeLastSeries(s).trim();
        //去除后缀如:(英|日|韩)文版 (英|日|韩)语版
        s = removeLastWen(s).trim();

        LOGGER.info(String.format("removeCpNameLastString,转换前:%s 转换后:%s", tmp, s));
        //如果去除完后成了空字符串,直接返回传过来的值
        if (StringUtils.isEmpty(s)) {
            s = tmp;
        }
        return s;
    }

    /**
     * 从更新信息中提取总集数
     * <p>
     * 格式化总集数,格式化为(\d{1,4})
     * 以下格式需要提取,形如:
     * 共25集全
     * 共25期全
     * 25集全
     * 25期全
     * 其他格式为空
     *
     * @param ottUpdateInfo
     * @return
     */
    public static String getTotalNumeByOttUpdateInfo(String ottUpdateInfo) {
        if (StringUtils.isEmpty(ottUpdateInfo)) {
            return "";
        }
        String pattern = "^共?([\\d]{1,4})(集|期)全$";
        String result = StringUtils.EMPTY;
        Matcher m = Pattern.compile(pattern).matcher(ottUpdateInfo);
        while (m.find()) {
            result = m.group(1);
        }
        return result;
    }

    /**
     * 判断字符串是否是日期格式
     *
     * @param s
     * @return
     */
    public static boolean isDateFormat(String s) {
        if (StringUtils.isEmpty(s)) {
            return false;
        }
        String pattern = "([\\d]{4}-[\\d]{1,2}-[\\d]{1,2})";
        Matcher m = Pattern.compile(pattern).matcher(s);
        return m.matches();
    }

    public static void main(String[] args) {
//        System.out.println(mReverseNumbers("央视春节联欢晚会 2016"));
//        System.out.println(mReplaceNumbers("天眼 Ⅲ"));
//        System.out.println(mReplaceJI("天眼 第四"));
//        System.out.println(reverseByWhiteSpace("萌学园 第四季 时空战役"));
//        String s = relateWordReplace("天 四眼,——  第四季  粤语版");
//        System.out.println(s);
//        String clipName = "我爱你,再见";
//        System.out.println(relateWordReplace(clipName));
//        System.out.println(relateWordReplace("激情燃烧的岁月 第三部"));
//        System.out.println(relateWordReplace("激情燃烧的岁月3"));

//        System.out.println(getTotalNumeByOttUpdateInfo("共25集全"));
//        System.out.println(getTotalNumeByOttUpdateInfo("25集全"));
//        System.out.println(getTotalNumeByOttUpdateInfo("共25期全"));
//        System.out.println(getTotalNumeByOttUpdateInfo("25期全"));
        System.out.println(isDateFormat("1987-01-02"));
//        Integer t1 = 2;
//        Integer t2 = 3;
//        System.out.println(t1.compareTo(t2));
    }
}