如何使用grep提取分隔符为,/.-且分隔符统一的合法日期
问题原因
你当前使用的正则没有限制两个分隔符必须为同一符号,两处分隔符的匹配规则完全独立,因此会命中分隔符混用的无效数据。
修正方案
使用捕获组+反向引用的规则,把第一个出现的分隔符捕获后,要求第二个分隔符和捕获的内容完全一致,同时补充年、月、日的合法性匹配规则,避免出现月份为350这类无效值。
如果仅匹配你给出的样例范围的日期,修正后的代码如下:
grep("^(?:[ ']*20|')?\\d{2}([,./-])0?[1-9]\\10?[1-9]$", year, value = T)
如果需要兼容10-12月、10号以上的通用合法日期,可以使用更严谨的版本:
grep("^(?:[ ']*20|')?\\d{2}([,./-])(0?[1-9]|1[0-2])\\1(0?[1-9]|[12][0-9]|3[01])$", year, value = T)
规则说明
^(?:[ ']*20|')?:匹配开头可选前缀,支持两种年格式:带可选空格/单引号前缀的4位年(如2019、'2019)、带单引号前缀的2位年(如'21)\\d{2}:匹配年份的最后两位数字([,./-]):捕获第一个分隔符,限定只能是逗号、斜杠、点、连接符中的一种- 月份匹配规则:
(0?[1-9]|1[0-2]),支持1位或带前导0的2位合法月份 \\1:反向引用第一个捕获的分隔符,要求和第一个分隔符完全一致,保证分隔符统一- 日期匹配规则:
(0?[1-9]|[12][0-9]|3[01]),支持1位或带前导0的2位合法日期 $:匹配到字符串结尾,避免多余后缀字符
运行结果
执行上述代码后返回的匹配结果如下,完全符合你的要求:
[1] "2019,3,1" "2019,03,01" "2019.03.01" "2019-03-01" " '21/3/1"
内容的提问来源于stack exchange,提问作者ovcovc
相关产品推荐
相关产品推荐

