/**
* 正则表达式工具
* 参考:正则表达式验证日期(多种日期格式)——转载 - 一个码农的成长之路 - 博客园
*/
import java.text.SimpleDateFormat;
import java.util.Calendar;
/**
*
* @author javaxboy@163.com
*/
public class RegexForDate {
final static private String commonYearRule = "(?!0000)[0-9]{4}";
final static private String leapYearRule = "(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)";//闰年规则
final static private String allMonthRule = "(?:0[1-9]|1[0-2])";//所有月份
final static private String date28Rule = "(?:0[1-9]|1[0-9]|2[0-8])";//都有0-28
final static private String monthExcFebRule = "(?:0[13-9]|1[0-2])";//除2月外
final static private String date30Rule = "(?:29|30)";//都有29和30
final static private String oddMonthRule = "(?:0[13578]|1[02])";//所有大月都有31
final static private String oddMonthDateRule = "(?:[0-2][1-9]|3[0-1])"; //大月规则
final static private String hourRule = "(?:20|21|22|23|[0-1][0-9])";//小时规则
final static private String minuteAndSecondRule = "(?:[0-5][0-9])";//分钟和秒数规则
final static private String milliSecondRule = "(?:[0-9]{3})";//毫秒数规则
/**
* 标准格式:
* (yearRule-(
* (allMonthRule-date28Rule)
* |(monthExcFebRule-date30Rule)
* |(bigMonthRule-31)
* )
* )
* |(leapYear-02-29)
* 处理逻辑
* 1、将整个格式化字符串分为
* yearStr = 年份片段,
* mdStr = 日期+月份片段(相邻,但前后不确定),
* timeStr=时间片段(顺序固定在整个串的末端最少有HH)
* 2、复制dateFormat生成2月29日的校验的规则
*
* @param dateFormat
* @return
*/
public static String getDateRegexRule(String dateFormat){
int yPos = dateFormat.indexOf("yyyy");
int mPos = dateFormat.indexOf("MM");
int dPos = dateFormat.indexOf("dd");
if(yPos<0 || mPos<0 || dPos<0){
return "";
}
int hPos = dateFormat.indexOf("HH");
String ymdStr,timeStr;
if(hPos<0){
ymdStr = dateFormat;
timeStr = "";
}else{
ymdStr = dateFormat.substring(0, hPos);
timeStr = dateFormat.substring(hPos);
}
timeStr = timeStr.replace("HH", hourRule)
.replace("mm", minuteAndSecondRule)
.replace("ss", minuteAndSecondRule)
.replace("SSS", milliSecondRule);
int minPos = Math.min(mPos, dPos);
int maxPos = Math.max(mPos, dPos)+2;
String mdStr = dateFormat.substring(minPos, maxPos);
String d28 = mdStr.replace("MM", allMonthRule).replace("dd", date28Rule);
String d30 = mdStr.replace("MM", monthExcFebRule).replace("dd", date30Rule);
String d31 = mdStr.replace("MM", monthExcFebRule).replace("dd", "31");
String du = "(?:" + d28 + "|" + d30 + "|" + d31 + ")";
String yStr = ymdStr.replace("yyyy", commonYearRule).replace(mdStr, du);
String leapYStr = ymdStr.replace("yyyy", leapYearRule).replace("MM", "02").replace("dd", "29");
String rule = "(?:" + yStr + ")|(?:" + leapYStr + ")" + timeStr;
return rule;
}
public static void main(String args[]){
String fmt = "yyyy年MM月dd日";
SimpleDateFormat sdf = new SimpleDateFormat(fmt);
String regexRule = getDateRegexRule(fmt);
Calendar date= Calendar.getInstance();
String dateStr;
date.add(Calendar.DATE, 1);
for(int i=0;i<100;i++){
date.add(Calendar.MONTH, -7);
dateStr = sdf.format(date.getTime());
System.out.println("文本格式:"+dateStr);
System.out.println("正则校验:"+dateStr.matches(regexRule));
System.out.println("");
}
}
}