如何编写符合[#d][#h][#m][#s]格式的Java时长验证正则表达式?
时长格式验证的Java正则表达式问题解决
问题描述
需要编写支持#d#h#m#s格式的Java正则表达式验证时长,规则如下:
d代表天、h代表小时、m代表分钟、s代表秒- 各字段可选,但必须按天→小时→分钟→秒的顺序排列
- 有效示例:
1h2s、1m、2m15s - 无效示例:
2m1h(顺序错误)、2k30s(非法单位)
尝试了如下代码,但所有输入都被判定为有效,添加$后缀后问题仍存在:
String duration = "2d0k15s"; try { duration.matches("(\\d+d)?(\\d+h)?(\\d+m)?(\\d+s)?"); System.out.println("Valid."); } catch (final PatternSyntaxException pse) { System.out.println("Not valid! " + pse.getMessage()); }
问题原因
- 未判断
matches的返回值:代码仅调用了matches方法,但没有根据返回的布尔值判断有效性,无论匹配成功与否都会执行System.out.println("Valid.")。 - 正则表达式存在缺陷:原正则允许空字符串通过验证,且没有明确确保至少包含一个有效时长字段。
解决方案
优化后的正则表达式
使用如下正则,满足顺序要求、禁止空输入、仅允许合法单位:
^(?!$)(?:\\d+d)?(?:\\d+h)?(?:\\d+m)?(?:\\d+s)?$
(?!$):负前瞻断言,确保输入不是空字符串(?:\\d+d)?:可选的天字段(非捕获分组,避免不必要的内存消耗)- 后续
(?:\\d+h)?、(?:\\d+m)?、(?:\\d+s)?同理,严格按天→小时→分钟→秒的顺序排列
修改后的代码
String duration = "2d0k15s"; try { boolean isValid = duration.matches("(?!$)(?:\\d+d)?(?:\\d+h)?(?:\\d+m)?(?:\\d+s)?"); if (isValid) { System.out.println("Valid."); } else { System.out.println("Not valid!"); } } catch (final PatternSyntaxException pse) { System.out.println("Not valid! " + pse.getMessage()); }
验证测试
- 输入
1h2s→ 输出Valid. - 输入
2m1h→ 输出Not valid! - 输入
2k30s→ 输出Not valid! - 输入空字符串 → 输出
Not valid!
内容的提问来源于stack exchange,提问作者abhimanyue
相关产品推荐
相关产品推荐

