项目需要爬取全网的媒资内容并将相同的媒资融合在一起,例如腾讯有天龙八部,芒果也有天龙八部,这样就会生成一个天龙八部的融合合集,下面关联不同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));
}
}