如何替换所有数字但不修改符合指定格式的日期内容?
问题原因
你当前的正则逻辑完全搞反了预查的作用:(?!2021\-[0-1][0-9]\-[0-3]\d)\d 表示仅匹配「右侧没有紧跟2021-xx-xx串」的数字做替换。但对于2021-07-15这类合法日期内的数字,除了串首位置,后续所有数字的右侧都不会出现2021开头的格式串,因此都会被替换成0,最终出现2000-00-00的错误结果。同时你硬编码了年份为2021,无法适配其他年份的日期。
解决方案
推荐使用优先匹配跳过日期的正则策略,兼容性最强,适配所有符合规则的日期场景:
- 正则表达式:
(\d{4}-\d{2}-\d{2}(?:\.\d+)?)|\d - 替换规则:如果第一个捕获组存在内容,直接返回捕获组原内容;否则返回
0
规则说明
- 优先匹配完整的合法日期串(含可选的小数点后缀),放入第一个捕获组,这部分内容会被直接保留不替换
- 剩余未被匹配到的单个数字,全部命中替换规则,替换为0
效果验证
| 输入 | 输出 | 说明 |
|---|---|---|
1111.21 | 0000.00 | 无匹配日期,所有数字替换为0 |
1111 | 0000 | 无匹配日期,所有数字替换为0 |
2021-07-15 | 2021-07-15 | 匹配到日期串,直接保留 |
2021-07-15.0000 | 2021-07-15.0000 | 匹配到带后缀的日期串,直接保留 |
1234 | 0000 | 无匹配日期,所有数字替换为0 |
限定单字符负向预查的特殊场景方案
如果你的运行环境只能使用匹配单个字符的负向预查表达式,可使用如下规则:
\d(?!(?:\d{0,3}-\d{2}-\d{2}|\d{0,1}-\d{2}|\d{0,2})(?:\.\d+)?\b)
该规则通过判断当前数字右侧是否为日期格式的剩余部分,来排除掉日期内的数字,仅匹配需要替换的数字。
内容的提问来源于stack exchange,提问作者Moon sungho
相关产品推荐
相关产品推荐

