如何用REGEXP_LIKE筛选数据库中非MM/DD/YYYY格式的数据
筛选非MM/DD/YYYY格式的日期数据
嘿,我来帮你搞定这个正则筛选的问题!你现在的思路是对的——用NOT REGEXP_LIKE排除符合目标格式的数据,但现有正则还有可以优化的地方,尤其是如果要更精准匹配严格的MM/DD/YYYY格式的话。
先说说你现有正则的小问题
你当前用的[0-9][0-9]/[0-9][0-9]/[0-9]{4}确实能匹配类似XX/XX/XXXX的字符串,但它有两个潜在问题:
- 没有用锚点
^和$,如果字段内容是01/01/2023 14:30这种带时间的字符串,正则会匹配到其中的日期部分,导致这条数据不会被筛选出来,但它其实不符合纯MM/DD/YYYY格式。 - 它会匹配逻辑无效的日期(比如
13/99/2023),如果你只是想筛选格式不符合的(不管日期是否合理),这一点影响不大;但如果要同时排除格式符合但逻辑无效的日期,就需要更严谨的正则。
优化后的正则方案
方案1:仅匹配格式严格符合MM/DD/YYYY的(不验证日期逻辑有效性)
如果你只关心格式是否为两位数字/两位数字/四位数字,给正则加上锚点,确保整个字段内容完全匹配:
SELECT birth_date FROM table_name WHERE NOT REGEXP_LIKE(birth_date, '^[0-9]{2}/[0-9]{2}/[0-9]{4}$');
这个正则会把所有不是XX/XX/XXXX格式的数据(比如dd-mon-yy、yyyy/mm/dd、带时间的日期、非标准格式内容)都筛选出来。
方案2:匹配格式+逻辑有效的MM/DD/YYYY日期
如果想同时排除那些格式符合但日期逻辑无效的数据(比如13/32/2023),可以用更精准的正则:
SELECT birth_date FROM table_name WHERE NOT REGEXP_LIKE(birth_date, '^(0[1-9]|1[0-2])/(0[1-9]|[12][0-9]|3[01])/[0-9]{4}$');
这个正则的各部分含义:
^(0[1-9]|1[0-2]):匹配01-12的有效月份(0[1-9]|[12][0-9]|3[01]):匹配01-31的有效日期(覆盖大部分月份的合理范围,若要精准处理闰年2月的特殊情况,正则会复杂很多,一般场景下这个程度足够)[0-9]{4}:匹配四位数字的年份^和$:确保整个字段内容完全符合这个格式,没有多余字符
特殊情况处理:包含NULL值
如果你的birth_date字段有NULL值,REGEXP_LIKE对NULL会返回NULL,NOT NULL还是NULL,所以这些NULL值不会出现在结果里。如果要把NULL也筛选出来,可以修改条件:
SELECT birth_date FROM table_name WHERE NOT REGEXP_LIKE(birth_date, '^(0[1-9]|1[0-2])/(0[1-9]|[12][0-9]|3[01])/[0-9]{4}$') OR birth_date IS NULL;
内容的提问来源于stack exchange,提问作者Shubham Sharan
相关产品推荐
相关产品推荐

