如何正确地转义和取消包含换行文字的多行字符串?
问题描述:
我正在使用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。你必须确定斜杠的数量。通过一次性完成所有这些,通过同时解码这些引导斜线来避免这个问题。
感谢您的回答,我想保持一段时间的打开,虽然也许有人来过,可能知道这是否可以使用VSCode API来完成。 – m90