首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

也问个正则表达式的有关问题

2012-02-24 
也问个正则表达式的问题日期格式的字符串,可能有以下格式:2008-10-112009-10-11 23:22(日期和时间之间

也问个正则表达式的问题
日期格式的字符串,可能有以下格式:
'2008-10-11'
'2009-10-11 23:22'(日期和时间之间是空格)
'2009-10-11 23:22:49'
日期分隔符可以是'-','/','.',但这3种情况下时间分隔符一定是':'
日期也可能是'年月日',但此时时间分隔符可能是':'('2009年01月11日 23:22:23'),也可能是'时分秒'('2009年01月11日 23时22分23秒')

不会出现其他情况

求验证表达式,并能转化为java.util.Date




[解决办法]
比较复杂
(\d{4}[-/\.]{1}\d{2}[-/\.]{1}\d{2}(\s{1}\d{2}:\d{2}(:\d{2}){0,1}){0,1})
|
(\d{4}年}\d{2}月\d{2}日(\s{1}\d{2}:\d{2}(:\d{2}){0,1}){0,1}) 
|
(\d{4}年}\d{2}月\d{2}日(\s{1}\d{2}时\d{2}分(\d{2}秒){0,1}){0,1})

分成了三个分支结构,由“|”(意同或)连接。

其中对于月份,日期,时,分,秒等数字合理性的判断没写在里面,免得太长,影响阅读理解。
具体数字的范围判断如下,可以逐个按照位置上面的正则里
月 0{1}/d{1}|10|11|12
日 [0-2]{1}/d{1}|30|31
时 [0-1]{1}/d{1}|20|21|22|23
分 [0-5]{1}/d{1}
秒 [0-5]{1}/d{1}
[解决办法]
关注,坐坐sf.
[解决办法]
前不久我也问过正则表达式的,呵呵,帮顶了,感觉正则表达式功能很大!
[解决办法]
个人看法,别自己跟自己过不去
从设计上将,一个日期同时出现你说的几个情况本身就是个错误。
从另一个角度讲,你完全可以
1 将/-等全部去掉
2 然后直接解析 20090110 这样的格式
3 包含时间的应该单独解析,我从未遇到过同时允许没有时间的情况
[解决办法]
顶java2000_net
不要把简单的事情复杂化~
[解决办法]
由于日期涉及闰年、大月、小月问题,因此日期的正则表达式非常复杂,加上又有那么多的格式和时间,
写出来的话,正则表达式字符长度将会超过 400 个字符。

建议使用正则表达式验证基本的数据格式,至于数据的合法性应采用代码逻辑进行验证。


原来在 CSDN 的 blog 里写的,带有行内嵌注释:

Java code
   1. import java.util.regex.Matcher;     2. import java.util.regex.Pattern;     3.      4. public class DateRegex {         5.      6.     public static void main(String[] args) {     7.         String[] str = {     8.                 "2001-00-00", "2001-01-01", "2001-01-30", "2001-01-31",     9.                 "2001-01-32", "2001-02-01", "2001-02-27", "2001-02-28",    10.                 "2004-02-29", "2001-02-29", "2001-02-30", "2001-02-31",    11.                 "2001-02-32", "2001-03-01", "2001-03-10", "2001-03-29",    12.                 "2001-03-30", "2001-03-31", "2001-03-32", "2001-04-01",    13.                 "2001-04-10", "2001-04-29", "2001-04-30", "2001-04-31",    14.                 "2001-04-32", "2001-05-01", "2001-05-10", "2001-05-29",    15.                 "2001-05-30", "2001-05-31", "2001-05-32", "2001-06-01",    16.                 "2001-06-10", "2001-06-29", "2001-06-30", "2001-06-31",    17.                 "2001-06-32", "2001-07-01", "2001-07-10", "2001-07-29",    18.                 "2001-07-30", "2001-07-31", "2001-07-32", "2001-08-01",    19.                 "2001-08-10", "2001-08-29", "2001-08-30", "2001-08-31",    20.                 "2001-08-32", "2001-09-01", "2001-09-10", "2001-09-29",    21.                 "2001-09-30", "2001-09-31", "2001-09-32", "2001-10-01",    22.                 "2001-10-10", "2001-10-29", "2001-10-30", "2001-10-31",    23.                 "2001-10-32", "2001-11-01", "2001-11-10", "2001-11-29",    24.                 "2001-11-30", "2001-11-31", "2001-11-32", "2001-12-01",    25.                 "2001-12-10", "2001-12-29", "2001-12-30", "2001-12-31",    26.                 "2001-12-32", "2001-13-01", "2001-13-10", "2001-13-29",    27.                 "2001-13-30", "2001-13-31", "2001-13-32", "245-12-04",    28.                 "100-02-29" , "200-02-29" , "300-02-29" , "400-02-29",    29.                 "500-02-29" , "800-02-29" , "900-02-29" , "2008-02-29",    30.                 "1900-02-29", "2000-02-29", "1-01-01"   , "1-02-28",    31.                 "0-01-01"   , "1-12-31"   , "351-02-29" , "352-02-29",    32.                 "353-02-29" , "354-02-29" , "355-02-29" , "356-02-29",    33.                 "357-02-29" , "358-02-29" , "350-02-29" , "1-02-29",    34.                 "2-02-29"   , "3-02-29"   , "4-02-29"   , "5-02-29",    35.                 "6-02-29"   , "7-02-29"   , "8-02-29"   , "9-02-29",    36.                 "10-02-29"  , "11-02-29"  , "12-02-29"  , "13-02-29",    37.                 "14-02-29"  , "15-02-29"  , "16-02-29"  , "17-02-29",    38.                 "18-02-29"  , "19-02-29"  , "20-02-29"  , "21-02-29",    39.                 "22-02-29"  , "23-02-29"  , "24-02-29"  , "25-02-29",    40.                 "26-02-29"  , "27-02-29"  , "28-02-29"  , "29-02-29",    41.                 "0-01-12"   , "00-01-12"  , "000-01-12" , "0000-01-12",    42.                 "0028-02-29"    43.             };    44.     45.         String moreMonth =    46.                 "(?:                         \n" +    47.                 "   ## 日期前是大月              \n" +    48.                 "   ## 01 03 05 07 08        \n" +    49.                 "   ## 10 12 月                 \n" +    50.                 "   (?<=                     \n" +    51.                 "       (?:                  \n" +    52.                 "           0[13578]         \n" +    53.                 "           |                \n" +    54.                 "           1[02]            \n" +    55.                 "       )                    \n" +    56.                 "       -                    \n" +   // 分隔符    57.                 "   )                        \n" +    58.                 "   (?:                      \n" +    59.                 "       ## 大月的日期 29       \n" +    60.                 "       29                   \n" +    61.                 "       |                    \n" +    62.                 "       ## 大月的日期 30~31    \n" +    63.                 "       3[01]                \n" +    64.                 "   )                        \n" +    65.                 ")                           \n";    66.     67.         String lesserMonth =     68.                 "(?:                         \n" +    69.                 "   ## 日期前是小月              \n" +    70.                 "   ## 04 06 09 11 月         \n" +    71.                 "   (?<=                     \n" +    72.                 "       (?:                  \n" +    73.                 "           0[469]           \n" +    74.                 "           |                \n" +    75.                 "           11               \n" +    76.                 "       )                    \n" +    77.                 "       -                    \n" +   // 分隔符    78.                 "   )                        \n" +    79.                 "   (?:                      \n" +    80.                 "       ## 小月的日期 29       \n" +    81.                 "       29                   \n" +    82.                 "       |                    \n" +    83.                 "       ## 小月的日期 30~31    \n" +    84.                 "       30                   \n" +    85.                 "   )                        \n" +    86.                 ")                           \n";    87. 


[解决办法]

Java code
  88.     String feburary =   
89.        "(?:                      \n" + 
90.        "  ## 29 号必须满足的条件,闰年            \n" + 
91.        "  (? <=                    \n" + 
92.        "    (?:                  \n" + 
93.        "      ## 被 4 整除的年份            \n" + 
94.        "      ## 除去最后两位为 0 的年份        \n" + 
95.        "      ## 最后两位数一定是:          \n" + 
96.        "      ##  20 40 60 80          \n" + 
97.        "      ## 04 24 44 64 84          \n" + 
98.        "      ## 08 28 48 68 88          \n" + 
99.        "      ## 12 32 52 72 92          \n" + 
100.        "      ## 16 36 56 76 96          \n" + 
101.        "      (?:                \n" + 
102.        "        [0-9]{0,2}(?!0?0)        \n" + 
103.        "        (?:              \n" + 
104.        "          ## 当尾数为[048]时前面不允是  \n" + 
105.        "          ## [13579]中的任何一个    \n" + 
106.        "          [02468]?(? <![13579])[048]  \n" + 
107.        "          |              \n" + 
108.        "          [13579][26]        \n" + 
109.        "        )                \n" + 
110.        "      )                  \n" + 
111.        "      |                  \n" + 
112.        "      ## 能被 400 整除的年份          \n" + 
113.        "      ## 其头两位数字规定同上          \n" + 
114.        "      (?:                \n" + 
115.        "        (?:              \n" + 
116.        "          [02468]?[048]        \n" + 


117.        "          |              \n" + 
118.        "          [13579][26]        \n" + 
119.        "        )                \n" + 
120.        "        00                \n" + 
121.        "      )                  \n" + 
122.        "    )                    \n" + 
123.        "    -02-                  \n" +  // 02 前后为分隔符 
124.        "  )                      \n" + 
125.        "  (?:29)                    \n" + 
126.        ")                        \n"; 
127. 
128.    String debugRegex = 
129.        "(?x:                \n" + 
130.        "  ## 年份 0001~9999,并忽略0年    \n" + 
131.        "  (?:[0-9]{1,4}(? <!^0?0?0?0))    \n" + 
132.        "  -                \n" +  // 分隔符 
133.        "  ## 月份                \n" + 
134.        "  (?:                \n" + 
135.        "    0[1-9]            \n" + 
136.        "    |              \n" + 
137.        "    1[0-2]            \n" + 
138.        "  )                \n" + 
139.        "  -                \n" +  // 分隔符 
140.        "  (?:                \n" + 
141.        "    ## 每个月都有的公共日期 01~09  \n" + 
142.        "    0[1-9]            \n" + 
143.        "    |              \n" + 
144.        "    ## 每个月都有的公共日期 10~19  \n" + 
145.        "    1[0-9]            \n" + 
146.        "    |              \n" + 
147.        "    ## 每个月都有的公共日期 20~28  \n" + 
148.        "    2[0-8]            \n" + 


149.        "    |              \n" + 
150.              moreMonth          + 
151.        "    |              \n" + 
152.              lesserMonth          + 
153.        "    |              \n" + 
154.              feburary          + 
155.        "  )                \n" + 
156.        ")";     
157. 
158.    Pattern pattern = Pattern.compile(debugRegex); 
159.    Matcher matcher = pattern.matcher(""); 
160.    for(String s : str) { 
161.      matcher.reset(s); 
162.      System.out.println(s + " " + matcher.matches()); 
163.    } 
164.  } 
165. }



上面那个是带注释用于调试用的,去掉空格、注释和换行后正式用的是这样的:

Java code
(?:[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)))
[解决办法]
是的,这种很难进行配置,由于你所要求的格式太多,而且表达式除了闰年、大月、小月在内的逻辑之外,还带有
其他的逻辑(日期分隔符可以是'-','/','.',但这3种情况下时间分隔符一定是':' ),带有逻辑的东西正则表达
式都很难实现,就算实现了字符数将非常之多,验证效率也很低,还有可能会存在很多的 bug。由于表达式很长,
而且相似的字符也很多,直接导致测试和修改都会变得极其困难。
[解决办法]
LZ,我是来拿分的^_^
[解决办法]
正则表达式花样很多
但用的多的也就这几个
看看我的总结
http://blog.csdn.net/terryzero/archive/2009/01/05/3716115.aspx
[解决办法]
我觉得也是,正则是工具但不是万能的工具,呵呵,有些东西用逻辑代码搞定的话更方便
[解决办法]
xx
[解决办法]
支持火龙果和老紫竹..
有时候就是要不求甚解..
[解决办法]
俺是进来学习的^_^
[解决办法]
恩。正则表达式 不是万能的。
只不过是能简化了一些操作。
你可以试试用别的方法去实现。
因为一个事情不会仅仅就有一个解决方式。
答案是丰富多彩的。
[解决办法]
探讨
比较复杂 
(\d{4}[-/\.]{1}\d{2}[-/\.]{1}\d{2}(\s{1}\d{2}:\d{2}(:\d{2}){0,1}){0,1}) 

(\d{4}年}\d{2}月\d{2}日(\s{1}\d{2}:\d{2}(:\d{2}){0,1}){0,1}) 

(\d{4}年}\d{2}月\d{2}日(\s{1}\d{2}时\d{2}分(\d{2}秒){0,1}){0,1}) 

分成了三个分支结构,由“|”(意同或)连接。 

其中对于月份,日期,时,分,秒等数字合理性的判断没写在里面,免得太长,影响阅读理解。 
具体数字的范围判断如下,可以逐个按照位置…

[解决办法]
学习
[解决办法]
写死得了 别让客户端那么多花样
[解决办法]
有平润年的问题,不好写。
------解决方案--------------------


在处理日期前,先设置日期的格式,这样处理才简单
[解决办法]
换个实现方法,干脆不用正则表达式,使用 Ext 或类似 JavaScript UI 库里的 DatePicker 组件供用户选择日期和时间,没有输入的过程,选择的时间日期的格式就固定了,只要在 Server 端按固定的格式校验或直接解析字符串到 Date 就 OK。这种一堆要求的客户就得拿这招对付他/她。
[解决办法]

探讨
换个实现方法,干脆不用正则表达式,使用 Ext 或类似 JavaScript UI 库里的 DatePicker 组件供用户选择日期和时间,没有输入的过程,选择的时间日期的格式就固定了,只要在 Server 端按固定的格式校验或直接解析字符串到 Date 就 OK。这种一堆要求的客户就得拿这招对付他/她。

[解决办法]
带时间选择的 JavaScript 组件这儿有一个:http://www.my97.net/dp/demo/
[解决办法]
探讨
引用:
......

但是服务器端的格式验证是不可少的啊。因为不排除有的人捣乱。

[解决办法]
jf
[解决办法]
mark+顶

热点排行
Bad Request.