这种比较简单,比如,今天,明天,下周,下月,明年,昨天,上周,上月,去年等。原理:匹配到明天就根据今天的时间天数加1。
/**
* 常用时间枚举
*
* @author xkzhangsan
*/
public enum CommonTimeEnum {
TODAY("today", "今天"),
TOMORROW("tomorrow", "明天"),
NEXTWEEK("nextWeek", "下周"),
NEXTMONTH("nextMonth", "下月"),
NEXTYEAR("nextYear", "明年"),
YESTERDAY("yesterday", "昨天"),
LASTWEEK("lastWeek", "上周"),
LASTMONTH("lastMonth", "上月"),
LASTYEAR("lastYear", "去年"),
;
private String code;
private String name;
public String getCode() {
return code;
}
public String getName() {
return name;
}
CommonTimeEnum(String code, String name) {
this.code = code;
this.name = name;
}
public static Map<String, String> convertToMap(){
Map<String, String> commonTimeMap = new HashMap<String, String>();
for (CommonTimeEnum commonTimeEnum : CommonTimeEnum.values()) {
commonTimeMap.put(commonTimeEnum.getCode(), commonTimeEnum.getCode());
commonTimeMap.put(commonTimeEnum.getName(), commonTimeEnum.getCode());
}
return commonTimeMap;
}
public static CommonTimeEnum getCommonTimeEnumByCode(String code){
for (CommonTimeEnum commonTimeEnum : CommonTimeEnum.values()) {
if(commonTimeEnum.getCode().equals(code)){
return commonTimeEnum;
}
}
return null;
}
}
/\*\*
\* 解析自然语言时间,今天,明天,下周,下月,明年,昨天,上周,上月,去年等。
\* @param text 自然语言时间,待解析字符串
\* @param naturalLanguageMap 自定义自然语言时间map,其中key自定义,value需为 com.xkzhangsan.time.enums.CommonTimeEnum中的code;
\* 可以为空,默认使用com.xkzhangsan.time.enums.CommonTimeEnum解析。
\* @return Date
\*/
public static Date parseNaturalLanguageToDate(String text, Map<String, String> naturalLanguageMap){
if(StringUtil.isEmpty(text)){
return null;
}
text = text.trim();
boolean isCommonTimeMap = false;
if(CollectionUtil.isEmpty(naturalLanguageMap)){
naturalLanguageMap = CommonTimeEnum.convertToMap();
isCommonTimeMap = true;
}
if(! naturalLanguageMap.containsKey(text) || StringUtil.isEmpty(naturalLanguageMap.get(text))){
return null;
}
String targetMethod = null;
if(isCommonTimeMap){
targetMethod = naturalLanguageMap.get(text);
}else{
String code = naturalLanguageMap.get(text);
Map<String, String> commonTimeMap = CommonTimeEnum.convertToMap();
if(commonTimeMap.containsKey(code)){
targetMethod = commonTimeMap.get(code);
}
}
if(targetMethod == null){
return null;
}
//执行结果
CommonTimeEnum targetCommonTime = CommonTimeEnum.getCommonTimeEnumByCode(targetMethod);
if(targetCommonTime == null){
return null;
}
switch (targetCommonTime){
case TODAY :
return DateTimeCalculatorUtil.today();
case TOMORROW:
return DateTimeCalculatorUtil.tomorrow();
case NEXTWEEK:
return DateTimeCalculatorUtil.nextWeek();
case NEXTMONTH:
return DateTimeCalculatorUtil.nextMonth();
case NEXTYEAR:
return DateTimeCalculatorUtil.nextYear();
case YESTERDAY:
return DateTimeCalculatorUtil.yesterday();
case LASTWEEK:
return DateTimeCalculatorUtil.lastWeek();
case LASTMONTH:
return DateTimeCalculatorUtil.lastMonth();
case LASTYEAR:
return DateTimeCalculatorUtil.lastYear();
default:
return null;
}
}
/\*\*
\* 明天
\* @return Date
\*/
public static Date tomorrow(){
return plusDays(today(), 1);
}
/\*\*
\* 今天
\* @return Date
\*/
public static Date today(){
return new Date();
}
这个是真实语境下的时间识别,比如 Hi,all.下周一下午三点开会,如果今天是2021-06-10 那么 返回结果为:2021-06-14 15:00:00 。
原理和第一种类似,也是识别时间词语,根据基准时间推断结果,但更强大一些。
基本分为三步:
(1)加载正则文件
(2)解析中文语句中的所有时间词语
(3)根据基准时间,循环解析(2)中的时间词语
详细步骤如图:
github: https://github.com/shinyke/Time-NLP
author:shinyke
由复旦NLP中的时间分析功能修改而来,做了很多细节和功能的优化。
简而言之,这是一个输入一句话,能识别出话里的时间的工具。
https://github.com/xkzhangsan/xk-time TimeNLPUtil
在Time-NLP基础上做了很多优化:
(1)封装属性,重命名使符合驼峰命名标准。
(2)将加载正则资源文件改为单例加载。
(3)将类按照功能重新划分为单独的多个类。
(4)使用Java8日期API重写。
(5)增加注释说明,优化代码。
(6)修复原项目中的issue:标准时间yyyy-MM-dd、yyyy-MM-dd HH:mm:ss和yyyy-MM-dd HH:mm解析问题。
(7)修复原项目中的issue:1小时后,1个半小时后,1小时50分钟等解析问题;并且支持到秒,比如50秒后,10分钟30秒后等。
(8)修复原项目中的issue:修复当前时间是上午10点,那么下午三点 会识别为明天下午三点问题。
(9)修复原项目中的issue:修复小数解析异常问题。
(10)性能优化,将使用到的正则预编译后放到缓存中,下次直接使用,提高性能。
第一种只能识别单词;
第二种也只能识别正则文件中的词语,比第一种识别能力更强,但如果有新的或不常用的时间词语无法处理,比如星期一的同义词礼拜一等,如果要不断支持新的词语,需要不断的修改,不如机器学习好;
对于常用的时间词语识别,第二种已经达到很高的识别率。
第一种实现,因为有网友需要识别中文时间词语,我写了第一种的实现;
第二种实现,另一个网友有需要识别语句中的中文时间词语,他向往推荐了Time-NLP这个项目,说这个项目很好,不维护了,有一些小问题,希望我能参考实现,我研究了原项目代码,在我的项目中重写,优化,并修复了一些问题。
感谢shinyke,这个项目很好,学习到很多正则解析的知识。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章