You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java正则匹配#包裹内容:replaceFirst替换异常求助

解决String.replaceFirst匹配范围过大导致替换错误的问题

我完全懂你遇到的坑——你用replaceFirst的时候,正则里的.*是贪婪模式,会从第一个#一路匹配到最后一个#,直接把两个动态表达式都包含进去了,所以第一次替换就把后半段的内容也给覆盖了,结果自然不对。

错误原因分析

你的正则表达式#(date)\\|(.*)\\|(.*)#中,.*是贪婪匹配,它会尽可能匹配最多的字符。所以当第一个#被匹配到后,它会跳过中间的#,直接匹配到整个字符串的最后一个#,导致第一次替换就把#date|Date debut|dd/MM/yyyy# 00:00:00','DD/MM/YYYY HH24:MI:SS') and update_date <= to_timestamp('#date|Date fin|dd/MM/yyyy#这一大段都当成了匹配内容,替换后只剩后面的尾巴。

两种可行的解决方案

方案1:改用非贪婪匹配模式

把正则里的.*换成.*?,?会让匹配变成非贪婪模式,匹配到下一个#就停止:

String content = "select * from queries where update_date >= to_timestamp('#date|Date debut|dd/MM/yyyy# 00:00:00','DD/MM/YYYY HH24:MI:SS') and update_date <= to_timestamp('#date|Date fin|dd/MM/yyyy# 23:59:59','DD/MM/YYYY HH24:MI:SS')";
String begin = "28/05/2018"; 
String end = "29/05/2018";

content = content.replaceFirst("#(date)\\|(.*?)\\|(.*?)#", begin);
content = content.replaceFirst("#(date)\\|(.*?)\\|(.*?)#", end);

方案2:匹配除#外的所有字符

用[^#]*代替.*,这样明确只匹配不包含#的字符,从根本上避免跨#匹配:

content = content.replaceFirst("#(date)\\|([^#]*)\\|([^#]*)#", begin);
content = content.replaceFirst("#(date)\\|([^#]*)\\|([^#]*)#", end);

正确结果

用上面任意一种方案,最终都会得到你想要的字符串:

select * from queries where update_date >= to_timestamp('28/05/2018 00:00:00','DD/MM/YYYY HH24:MI:SS') and update_date <= to_timestamp('29/05/2018 23:59:59','DD/MM/YYYY HH24:MI:SS')

内容的提问来源于stack exchange,提问作者Lexahen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:48:05