0

Ich arbeite an einer Visual Studio Code-Erweiterung. Die Erweiterung soll auf den Text einwirken, der gerade im Editorfenster ausgewählt ist, und an einen externen Befehl senden (lein-cljfmt in meinem Fall, aber ich denke, das hat nichts mit meiner Frage zu tun). Wenn der externe Befehl fertig ist, wird der Text verarbeitet, der den aktuellen Editorselektor durch das vom Befehlszeilenwerkzeug zurückgegebene Ergebnis ersetzen soll.Wie kann ich eine mehrzeilige Zeichenfolge, die Newline-Literale enthält, ordnungsgemäß entschlüsseln und nicht anzeigen?

Bevor die Zeichenfolge zu senden ich entkommen es wie folgt aus:

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

Das Ergebnis in wird unescaped wie:

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

Dies aber ein Fall in all arbeitet: wenn die Auswahl, die verarbeitet wird Enthält ein String-Literal, das ein Newline-Literal enthält, wird das Unescaping stattdessen in einen Zeilenumbruch umgewandelt, wodurch der Code im Editor aufgebrochen wird.

Dies ist ein Beispiel für ein Snippet, das mein Entkommen bricht:

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

Ich versuchte schon einige regexp schwarze Magie wie

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

jetzt finden konnte, aber nicht eine Lösung, die funktioniert Randfälle nicht haben. Gibt es eine Möglichkeit, dies zu tun, die ich vermisse? Ich frage mich auch, ob es eine VSCode-Erweiterung API gibt, die damit umgehen könnte, da es ein allgemeines Szenario für mich zu sein scheint.

Antwort

1

ich denke, das könnte sein, was Sie brauchen:

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 + ']'); 
 
});

Der Versuch, die Zeichenfolge in 3 Stufen unescape ist wirklich schwierig, weil \n eine andere Bedeutung in Abhängigkeit davon hat, wie viele Hiebe gibt es kurz davor. In Ihrem Beispiel wird die ursprüngliche Zeichenkette \n (Schrägstrich n) als \\n (Schrägstrich n) codiert. Wenn Sie sie entschlüsseln, stimmen die letzten beiden Zeichen mit der ersten Ihrer RegExps überein, wenn Sie wollen, dass die ersten beiden Zeichen übereinstimmen dritte RegExp. Sie müssen die Schrägstriche zählen, um sicher zu gehen. Wenn Sie alles auf einmal erledigen, vermeiden Sie dieses Problem, indem Sie gleichzeitig die führenden Schrägstriche dekodieren.

+0

Danke für die Antwort, ich möchte dies für eine Weile offen halten, da vielleicht jemand kommt, der vielleicht weiß, ob dies mit den VSCode-APIs gemacht werden kann. – m90

Verwandte Themen