如何删除JavaScript多行字符串中含import/required的指定行并保留换行
问题原因
原有实现直接通过split('\n')拆分字符串,无法区分两类换行:
- 代码结构层面的真实排版换行,也就是行与行之间的实际分隔符
- 代码内容中字符串字面量里的转义换行(比如示例中
'\t\n'里的\n,属于代码内容的一部分,不是行分隔符)
把内容层面的转义换行误判为行分隔符拆分,就会破坏原有内容结构,导致输出不符合预期。
正确实现
采用逐字符扫描的方式,跟踪扫描位置是否处于字符串字面量内部,仅当不在字符串内部时遇到的换行才判定为真实行分隔符,逐行判断是否保留,全程不修改原始内容的转义字符、换行格式。
function sanitizeSandbox(code) { if (typeof code !== 'string' || code.length === 0) return ''; const result = []; let currentLine = ''; // 跟踪是否处于单引号、双引号、模板字符串内部 let inSingleQuote = false; let inDoubleQuote = false; let inTemplate = false; // 标记前一个字符是否为转义符\,避免误判转义的引号为字符串边界 let isEscaped = false; for (let i = 0; i < code.length; i++) { const char = code[i]; currentLine += char; if (isEscaped) { isEscaped = false; continue; } if (char === '\\') { isEscaped = true; continue; } // 更新字符串边界状态 if (char === "'" && !inDoubleQuote && !inTemplate) { inSingleQuote = !inSingleQuote; continue; } if (char === '"' && !inSingleQuote && !inTemplate) { inDoubleQuote = !inDoubleQuote; continue; } if (char === '`' && !inSingleQuote && !inDoubleQuote) { inTemplate = !inTemplate; continue; } // 仅非字符串内部的换行属于真实行分隔 if (char === '\n' && !inSingleQuote && !inDoubleQuote && !inTemplate) { if (!currentLine.includes('import') && !currentLine.includes('required')) { result.push(currentLine); } currentLine = ''; } } // 处理末尾无换行的最后一行 if (currentLine.length > 0) { if (!currentLine.includes('import') && !currentLine.includes('required')) { result.push(currentLine); } } return result.join(''); }
效果说明
针对提供的示例测试:
- 包含
import的首行会被精准删除 - 最后一行
val += sc + '\t\n';中的\t\n属于字符串内部内容,不会被误判为行分隔符,完整保留 - 所有原始制表符、转义字符、真实换行格式和输入完全一致,不会出现错误拆分的问题。
内容的提问来源于stack exchange,提问作者Vladislav
相关产品推荐
相关产品推荐

