如何正确地转义和取消包含换行文字的多行字符串?

问题描述:

我正在使用Visual Studio代码扩展。该扩展应该对当前在编辑器窗口中选择的文本起作用,并将其发送给外部命令(在我的例子中为lein-cljfmt,但我认为这与我的问题无关)。当外部命令完成处理文本时,我想用命令行工具返回的结果替换当前的编辑器选择器。如何正确地转义和取消包含换行文字的多行字符串?

发送字符串之前我逃避这样的:

contents 
    .replace(/\\/g, '\\\\') 
    .replace(/"/g, '\\"') 
    .replace(/\n/g, '\\n'); 

结果在被转义,如:

contents 
    .replace(/\\n/g, '\n') 
    .replace(/\\"/g, '"') 
    .replace(/\\\\/g, '\\'); 

这适用于所有,但一个情况:当正在处理的选择包含一个包含新行文字的字符串文字,则不会将此转换为换行符,从而破坏编辑器中的代码。

这是打破我的逃逸片段的例子:

(defn join 
    [a b] 
    (str a "\n" b)) 

我试过很长一段正则表达式的黑魔法一样

.replace(/(?!\B"[^"]*)\\n(?![^"]*"\B)/g, '\n') 

现在,也没有找到一个解决方案,它没有边缘情况。有没有办法做到这一点,我失踪了?我也想知道是否有一个VSCode扩展API可以处理,因为它似乎是我常见的场景。

我认为这可能是你所需要的:

function slashEscape(contents) { 
 
    return contents 
 
     .replace(/\\/g, '\\\\') 
 
     .replace(/"/g, '\\"') 
 
     .replace(/\n/g, '\\n'); 
 
} 
 

 
var replacements = {'\\\\': '\\', '\\n': '\n', '\\"': '"'}; 
 

 
function slashUnescape(contents) { 
 
    return contents.replace(/\\(\\|n|")/g, function(replace) { 
 
     return replacements[replace]; 
 
    }); 
 
} 
 

 
var tests = [ 
 
    '\\', '\\\\', '\n', '\\n', '\\\n', '\\\\n', 
 
    '\\\\\n', '\\\\\\n', '\\"\\\\n', '\n\n', 
 
    '\n\n\n', '\\n\n', '\n\\n', '\\n\\n', 
 
    '\\\n\\n\nn\n\\n\\\n\\\\n', '"', '\\"', '\\\\"' 
 
]; 
 

 
tests.forEach(function(str) { 
 
    var out = slashUnescape(slashEscape(str)); 
 
    
 
    // assert that what goes in is what comes out 
 
    console.log(str === out, '[' + str + ']', '[' + out + ']'); 
 
});

试图取消转义字符串中的3个阶段是真正棘手,因为\n具有取决于有多少斜杠也有不同的含义就在它之前。在你的例子中,\n(斜杠n)的原始字符串被编码为\\n(斜线斜杠n),然后当你解码它时,最后两个字符与第一个RegExps匹配,当你想要的是前两个字符匹配第三RegExp。你必须确定斜杠的数量。通过一次性完成所有这些,通过同时解码这些引导斜线来避免这个问题。

+0

感谢您的回答,我想保持一段时间的打开,虽然也许有人来过,可能知道这是否可以使用VSCode API来完成。 – m90