Node.js中如何用正则替换SQL时排除注释与引号内内容?
解决SQL中CREATE TABLE正则替换误匹配注释与引号内容的问题
需求是在Node.js中处理SQL文件,给真正的CREATE TABLE语句前添加-split-分隔符,但现有正则会误匹配注释(多行/* */、单行--)和单引号内的create table文本,导致错误替换。
原始SQL内容
/* this is a comment for create table */ --this is another comment for create table create table test1 (comment varchar); create temporary table test2 (comment varchar); insert into text1 values('this is a comment for create table ')
原有替换代码
sqlText .replace(/\s+create(\s+|global\s+|temporary\s+)table\s+/gi, `-split- CREATE $1 TABLE `)
错误的实际输出
/* this is a comment for -split- CREATE TABLE */ --this is another comment for -split- CREATE TABLE -split- CREATE TABLE test1 (comment varchar); -split- CREATE temporary TABLE test2 (comment varchar); insert into text1 values('this is a comment for -split- CREATE TABLE ')
预期输出
/* this is a comment for create table */ --this is another comment for create table -split- CREATE TABLE test1 (comment varchar); -split- CREATE temporary TABLE test2 (comment varchar); insert into text1 values('this is a comment for create table ')
修正后的解决方案
要精准匹配仅处于代码上下文的create table,需要先排除注释和单引号字符串,使用带负向回顾断言的正则即可实现:
const correctedSql = sqlText.replace( /(?<!\/\*[^*]*\*+(?:[^/*][^*]*\*+)*\/|--[^\r\n]*|'[^']*(?:''[^']*)*')\s+create(\s+|global\s+|temporary\s+)table\s+/gi, `-split- CREATE $1 TABLE ` );
正则逻辑说明
这个正则通过(?<!...)负向回顾断言,确保当前匹配位置的左侧不属于以下三类内容:
- 多行注释:
\/\*[^*]*\*+(?:[^/*][^*]*\*+)*\/完整匹配从/*到*/的多行注释 - 单行注释:
--[^\r\n]*匹配从--开始到行尾的单行注释 - 单引号字符串:
'[^']*(?:''[^']*)*'匹配单引号包裹的文本,同时兼容SQL中用两个单引号转义的场景
这样就能彻底避免误替换注释或引号内的create table文本,只对真正的建表语句生效。
验证结果
用修正后的代码处理原始SQL,输出将完全符合预期:注释和引号内的内容保持不变,仅在create table和create temporary table语句前添加-split-分隔符。
内容的提问来源于stack exchange,提问作者Emrah
相关产品推荐
相关产品推荐

