闲着没事的时候,写了个验证日期的正则表达式,弄了大半天,头都大了。由于使用到了反向预搜索模式“(?<=)”和“(?
下面是源代码:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class DateRegex { public static void main(String[] args) { String[] str = { "2001-0-0", "2001-1-1", "2001-1-30", "2001-1-31", "2001-1-32", "2001-2-1", "2001-2-27", "2001-2-28", "2004-2-29", "2001-2-29", "2001-2-30", "2001-2-31", "2001-2-32", "2001-3-1", "2001-3-10", "2001-3-29", "2001-3-30", "2001-3-31", "2001-3-32", "2001-4-1", "2001-4-10", "2001-4-29", "2001-4-30", "2001-4-31", "2001-4-32", "2001-5-1", "2001-5-10", "2001-5-29", "2001-5-30", "2001-5-31", "2001-5-32", "2001-6-1", "2001-6-10", "2001-6-29", "2001-6-30", "2001-6-31", "2001-6-32", "2001-7-1", "2001-7-10", "2001-7-29", "2001-7-30", "2001-7-31", "2001-7-32", "2001-8-1", "2001-8-10", "2001-8-29", "2001-8-30", "2001-8-31", "2001-8-32", "2001-9-1", "2001-9-10", "2001-9-29", "2001-9-30", "2001-9-31", "2001-9-32", "2001-10-1", "2001-10-10", "2001-10-29", "2001-10-30", "2001-10-31", "2001-10-32", "2001-11-1", "2001-11-10", "2001-11-29", "2001-11-30", "2001-11-31", "2001-11-32", "2001-12-1", "2001-12-10", "2001-12-29", "2001-12-30", "2001-12-31", "2001-12-32", "2001-13-1", "2001-13-10", "2001-13-29", "2001-13-30", "2001-13-31", "2001-13-32", "245-12-4", "100-2-29" , "200-2-29" , "300-2-29" , "400-2-29", "500-2-29" , "800-2-29" , "900-2-29" , "2008-2-29", "1900-2-29", "2000-2-29", "1-1-1" , "1-2-28", "0-1-1" , "1-12-31" , "351-2-29" , "352-2-29", "353-2-29" , "354-2-29" , "355-2-29" , "356-2-29", "357-2-29" , "358-2-29" , "350-2-29" , "1-2-29", "2-2-29" , "3-2-29" , "4-2-29" , "5-2-29", "6-2-29" , "7-2-29" , "8-2-29" , "9-2-29", "10-2-29" , "11-2-29" , "12-2-29" , "13-2-29", "14-2-29" , "15-2-29" , "16-2-29" , "17-2-29", "18-2-29" , "19-2-29" , "20-2-29" , "21-2-29", "22-2-29" , "23-2-29" , "24-2-29" , "25-2-29", "26-2-29" , "27-2-29" , "28-2-29" , "29-2-29", "0-1-12" , "00-1-12" , "000-1-12" , "0000-1-12", "0028-2-29", "2007-1-31", "2007-11-31" }; String moreMonth = "(?: /n" + " ## 日期前是大月 /n" + " ## 01 03 05 07 08 /n" + " ## 10 12 月 /n" + " (?<= /n" + " - /n" + // 分隔符 " (?: /n" + " 0?[13578] /n" + " | /n" + " 1[02] /n" + " ) /n" + " - /n" + // 分隔符 " ) /n" + " (?: /n" + " ## 大月的日期 29 /n" + " 29 /n" + " | /n" + " ## 大月的日期 30~31 /n" + " 3[01] /n" + " ) /n" + ") /n"; String lesserMonth = "(?: /n" + " ## 日期前是小月 /n" + " ## 04 06 09 11 月 /n" + " (?<= /n" + " - /n" + // 分隔符 " (?: /n" + " 0?[469] /n" + " | /n" + " 11 /n" + " ) /n" + " - /n" + // 分隔符 " ) /n" + " (?: /n" + " ## 小月的日期 29 /n" + " 29 /n" + " | /n" + " ## 小月的日期 30~31 /n" + " 30 /n" + " ) /n" + ") /n"; String feburary = "(?: /n" + " ## 29 号必须满足的条件,闰年 /n" + " (?<= /n" + " (?: /n" + " ## 被 4 整除的年份 /n" + " ## 除去最后两位为 0 的年份 /n" + " ## 最后两位数一定是: /n" + " ## 20 40 60 80 /n" + " ## 04 24 44 64 84 /n" + " ## 08 28 48 68 88 /n" + " ## 12 32 52 72 92 /n" + " ## 16 36 56 76 96 /n" + " (?: /n" + " [0-9]{0,2}(?!0?0) /n" + " (?: /n" + " ## 当尾数为[048]时前面不允是 /n" + " ## [13579]中的任何一个 /n" + " [02468]?(?
上面的版本中仅适用于调试和修改,去掉空格、注释和换行后的精简模式如下,有 266 个字符(有误,2010-05-17删):
(?:[0-9]{1,4}(?
(2010-05-17 修)更新后为 273 个字符:
(?:[0-9]{1,4}(?