修改正则表达式以排除CASE语句后(含中间内容)的END;
正则表达式调整:排除CASE语句后的END;实例
需求说明
原本使用以下正则匹配文本中的END;:
const rightPattern = '\bEND\s*;';
需要修改为满足:
- 排除所有出现在
CASE语句之后的END;实例(CASE与END;之间可包含换行或任意文本) - 忽略
CASE语句后第一个END;之后的所有END;
示例输入文本
-- Example with END; after CASE CASE WHEN condition1 THEN END; -- Exclude this END; -- Another instance of END; not following CASE END; -- Example with line breaks and text between CASE and END; CASE WHEN condition2 THEN someText END; -- Exclude this END; -- Example with text between CASE and END; CASE WHEN condition3 THEN someText END; -- Exclude this END;
问题排查
原尝试的正则(?<!\bCASE.*)\bEND;存在两个问题:
.*默认不匹配换行符,无法处理CASE与END;跨多行的情况- 贪婪匹配导致范围覆盖过大,且未开启全局匹配,只能找到第一个结果
解决方案
方案1:支持ES2018+环境(如现代浏览器、Node.js 10+)
使用带反向预查的正则,开启全局、单行、多行模式:
const rightPattern = /(?<!\bCASE[\s\S]*?)\bEND\s*;/gms;
g:全局匹配所有符合条件的实例m:多行模式,适配行首行尾的匹配逻辑s:单行模式,让.匹配包括换行在内的所有字符(这里用[\s\S]等效,兼容性更好)(?<!\bCASE[\s\S]*?):反向预查,确保当前END;之前没有对应的CASE开头,且非贪婪匹配CASE到第一个END;的区间,避免误覆盖后续独立的END;
方案2:旧环境兼容(不支持反向预查量词)
采用“匹配排除区间+捕获目标内容”的思路:
const rightPattern = /\bCASE[\s\S]*?END;|(\bEND\s*;)/gms;
使用时需过滤空匹配,只保留捕获组的有效结果:
const inputText = `/* 你的输入文本 */`; const validMatches = []; let matchResult; while ((matchResult = rightPattern.exec(inputText)) !== null) { if (matchResult[1]) { validMatches.push(matchResult[1]); } } // validMatches即为所有符合要求的END;实例
核心要点
- 非贪婪匹配
*?:确保每次仅匹配CASE之后的第一个END;,避免影响后续独立的END; - 全局标志
g:必须添加,否则只会返回第一个匹配结果 [\s\S]:替代.实现跨换行的任意字符匹配,兼容性优于单行模式的.
内容的提问来源于stack exchange,提问作者Liza
相关产品推荐
相关产品推荐

