如何解决Javascript提取JPA命名参数时引号内内容误识别问题
问题根因
- 原有实现的
notStrRegex仅能处理简单的单/双引号边界场景,无法识别嵌套引号的情况。当字符串内部出现第二种引号时,正则的边界判断会失效,导致引号内部的内容也被纳入待提取范围,最终匹配到了不应该识别的参数。
修复方案
调整实现逻辑,先彻底清除所有被单/双引号包裹的内容(支持识别转义引号),再在剩余的非字符串内容中提取命名参数,从根源上规避引号内内容的干扰。
修复后的代码如下:
const namedParamRegex = /:([a-zA-Z0-9_]+)/g; /** * @returns array of named parameters which, * 1. always begins with : * 2. the remaining characters is guaranteed to be following [a-zA-Z0-9_] rule * * @example * 1. "select * from a where id = :myId3;" -> [':myId3'] * 2. "to_timestamp_tz(:FROM_DATE, 'YYYY-MM-DD\"T\"HH24:MI:SS')" -> [':FROM_DATE'] * 3. "TO_CHAR(ep.CHANGEDT,'yyyy=mm-dd hh24:mi:ss')" -> [] * 4. "\"user input invalid string ' :shouldIgnoreThisNamedParam ' in a string\"" -> [] */ export function extractNamedParam(query: string): string[] { // 移除所有被单/双引号包裹的内容,自动适配转义引号场景 const nonStrContent = query.replace(/(['"])(?:\\.|[^\\])*?\1/g, ''); // 匹配符合规则的命名参数 const params = nonStrContent.match(namedParamRegex) ?? []; // 可选:对参数去重,避免同个参数多次出现重复返回 return [...new Set(params)]; }
验证说明
修复后的代码可覆盖所有测试场景:
- 原有3个测试用例返回结果和之前完全一致,兼容原有逻辑
- 异常用例返回空数组,符合预期
内容的提问来源于stack exchange,提问作者Ka Chun Chan
相关产品推荐
相关产品推荐

