您的位置:首页 > 编程语言 > Java开发

验证日期的Java正则表达式

2010-05-26 14:18 405 查看
看火龙果写了一个验证日期的Java正则表达式,就给转了过来
由于使用到了反向预搜索模式“(?<=)”和“(?<!)”,所以这个只能在 Java 中使用,不能在 JavaScript 中使用,JavaScript 不支持反向预搜索。支持 yyyy-MM-dd、yyy-MM-dd、yy-MM-dd 和 y-MM-dd,即年份为 1~4 位数字,范围(1~9999,不存在公元 0 年),月和日应为两位数字(月和日要为一位数字的话还需要稍微修改一下),分隔符为“-”(凡是分隔符的地方都加上了注释,可以改成其他的字符)。
下面是源代码:
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]?(?<![13579])[048]   /n" +
"                   |                           /n" +
"                   [13579][26]                 /n" +
"               )                               /n" +
"           )                                   /n" +
"           |                                   /n" +
"           ## 能被 400 整除的年份                   /n" +
"           ## 其头两位数字规定同上                   /n" +
"           (?:                                 /n" +
"               (?:                             /n" +
"                   [02468]?[048]               /n" +
"                   |                           /n" +
"                   [13579][26]                 /n" +
"               )                               /n" +
"               00                              /n" +
"           )                                   /n" +
"       )                                       /n" +
"       -0?2-                                   /n" +   // 02 前后为分隔符
"   )                                           /n" +
"   (?:29)                                      /n" +
")                                              /n";
String debugRegex =
"(?x:                                /n" +
"   ## 年份 0001~9999,并忽略0年         /n" +
"   (?:[0-9]{1,4}(?<!^0?0?0?0))      /n" +
"   -                                /n" +   // 分隔符
"   ## 月份                               /n" +
"   (?:                              /n" +
"       0?[1-9]                       /n" +
"       |                            /n" +
"       1[0-2]                       /n" +
"   )                                /n" +
"   -                                /n" +   // 分隔符
"   (?:                              /n" +
"       ## 每个月都有的公共日期 01~09    /n" +
"       0?[1-9]                       /n" +
"       |                            /n" +
"       ## 每个月都有的公共日期 10~19    /n" +
"       1[0-9]                       /n" +
"       |                            /n" +
"       ## 每个月都有的公共日期 20~28    /n" +
"       2[0-8]                       /n" +
"       |                            /n" +
moreMonth                    +
"       |                            /n" +
lesserMonth                  +
"       |                            /n" +
feburary                     +
"   )                                /n" +
")";
Pattern pattern = Pattern.compile(debugRegex);
Matcher matcher = pattern.matcher("");
for(String s : str) {
matcher.reset(s);
System.out.println(s + " " + matcher.matches());
}
}
}


上面的版本中仅适用于调试和修改,去掉空格、注释和换行后的精简模式如下,有 266 个字符(有误,2010-05-17删):
(?:[0-9]{1,4}(?<!^0?0?0?0))-(?:0?[1-9]|1[0-2])-(?:0?[1-9]|1[0-9]|2[0-8]|(?:(?<=(?:0?[13578]|1[02])-)(?:29|3[01]))|(?:(?<=(?:0?[469]|11)-)(?:29|30))|(?:(?<=(?:(?:[0-9]{0,2}(?!0?0)(?:[02468]?(?<![13579])[048]|[13579][26]))|(?:(?:[02468]?[048]|[13579][26])00))-02-)(?:29)))
(2010-05-17 修)更新后为 273 个字符:
(?:[0-9]{1,4}(?<!^0?0?0?0))-(?:0?[1-9]|1[0-2])-(?:0?[1-9]|1[0-9]|2[0-8]|(?:(?<=-(?:0?[13578]|1[02])-)(?:29|3[01]))|(?:(?<=-(?:0?[469]|11)-)(?:29|30))|(?:(?<=(?:(?:[0-9]{0,2}(?!0?0)(?:[02468]?(?<![13579])[048]|[13579][26]))|(?:(?:[02468]?[048]|[13579][26])00))-0?2-)(?:29)))

查看原文:http://blog.csdn.net/bao110908/archive/2008/02/29/2132973.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: