如何修改正则替换不在引号中的SQL绑定参数(Java 8)
解决正则替换中引号内内容误加
?的问题 你的问题出在替换式"$1?"的逻辑上:无论匹配到的是引号内的文本(第一组)还是绑定参数(第二组),都会在匹配内容后追加?,导致引号内容被错误修改为'xxx'?。
修正方案(Java 8兼容)
使用Matcher的appendReplacement方法进行条件替换,精准区分两种匹配场景:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class BindVarProcessor { // 预编译正则,复用提升性能 private static final Pattern BIND_VAR_PATTERN = Pattern.compile("('[^\\n']*')|(:\\s*\\w+)"); public static String replaceBindVars(String value) { Matcher matcher = BIND_VAR_PATTERN.matcher(value); StringBuffer result = new StringBuffer(); while (matcher.find()) { if (matcher.group(1) != null) { // 匹配到引号内内容,直接保留原字符串 matcher.appendReplacement(result, Matcher.quoteReplacement(matcher.group(1))); } else { // 匹配到绑定参数,替换为? matcher.appendReplacement(result, "?"); } } // 追加剩余未匹配的内容 matcher.appendTail(result); return result.toString(); } public static void main(String[] args) { System.out.println("WHERE id = ? and productcode = ?" .equals(replaceBindVars("WHERE id = :id and productcode = :product_code"))); System.out.println("WHERE id = ? and productcode = '1:2 :3'" .equals(replaceBindVars("WHERE id = :id and productcode = '1:2 :3'"))); System.out.println("WHERE id = ? and code LIKE ': some-string with :colon and :bind_parameters' OR product_name LIKE ?'" .equals(replaceBindVars("WHERE id = :id and code LIKE ': some-string with :colon and :bind_parameters' OR product_name LIKE :product_name'"))); System.out.println("SELECT ? and ? WHERE id = 2 and product_code = 3" .equals(replaceBindVars("SELECT :id and :product_code WHERE id = 2 and product_code = 3"))); } }
逻辑说明
- 正则匹配逻辑不变:依然用
('[^\n']*')|(:\s*\w+)匹配两种目标,正则分支匹配遵循左优先原则,会优先识别引号内内容。 - 条件替换:
- 若
group(1)不为空,说明当前匹配的是引号内内容,直接将原内容写入结果(quoteReplacement用于处理内容中可能存在的特殊转义字符,避免干扰替换逻辑)。 - 若
group(1)为空,则匹配的是绑定参数,替换为?。
- 若
- 性能优化:预编译
Pattern对象,避免每次调用方法都重新编译正则表达式。
运行测试代码后,所有用例输出均为true,符合预期。
内容的提问来源于stack exchange,提问作者Evgenia
相关产品推荐
相关产品推荐

