web-dev-qa-db-ja.com

JavaScript-文字列リテラルのエスケープ文字の置き換え

JavaScript文字列リテラルのバックスラッシュ(エスケープ)文字を置き換えようとしています。

リダイレクトを実行できるように、二重のバックスラッシュに置き換える必要があります。

var newpath = 'file:///C:\funstuff\buildtools\viewer.html'.replace(/\\/g,"\\");
window.location = newpath;

しかし、結果はないようです。

Javascriptで処理される前にバックスラッシュを適切にエスケープするオプションはありません。

(\)を(\\)に置き換えてJavascriptを満足させるにはどうすればよいですか?

ありがとう、デレク

15
dbasch

リテラルの場合、バックスラッシュをエスケープする必要がありますbefore Javascriptはバックスラッシュを認識します。それを回避する方法はありません。

var newpath = 'file:///C:\\funstuff\\buildtools\\viewer.html';
window.location = newpath;

newpathが他の場所から値を取得していて、実際に単一のバックスラッシュが含まれている場合、それらを2つに増やす必要はありません。ただし、何らかの理由で本当に必要な場合は、replace()呼び出しでバックスラッシュをエスケープすることを忘れないでください。

newpath.replace(/\\/g,"\\\\");

なぜバックスラッシュをJavascriptで処理する前に適切にエスケープするオプションがないのですか?問題が、Javascriptソースが、\をエスケープ文字として使用する他のスクリプト言語から生成されている場合は、エスケープのレベルを追加するだけです。

var newpath = 'file:///C:\\\\funstuff\\\\buildtools\\\\viewer.html';
22
moonshadow

string-escaping behaviorをよりよく示し、理解するには、次の例をご覧ください。

文字列を分割することにより、JSエンジンによって解析された後、メモリ内で文字列がどのように見えるかを確認できます。したがって、この問題に関する潜在的な(醜い)ソリューションも提供します。

_'file:///C:\funstuff\buildtools\viewer.html'.split('')
//>
 ["f", "i", "l", "e", ":", "/", "/", "/", "C", ":", "", "u", "n", "s", "t", "u",
  "f", "f", "", "u", "i", "l", "d", "t", "o", "o", "l", "s", "", "i", "e", "w",
  "e", "r", ".", "h", "t", "m", "l"]

'file:///C:\funstuff\buildtools\viewer.html'.split('').map( function(e){
     return e.charCodeAt()
});
//>
[102, 105, 108, 101, 58, 47, 47, 47, 67, 58, 12, 117, 110, 115, 116, 117, 102,
 102, 8, 117, 105, 108, 100, 116, 111, 111, 108, 115, 11, 105, 101, 119, 101, 
 114, 46, 104, 116, 109, 108]
//>in Hex values by applying .toString(16)
["66", "69", "6c", "65", "3a", "2f", "2f", "2f", "43", "3a", "c", "75", "6e", 
 "73", "74", "75", "66", "66", "8", "75", "69", "6c", "64", "74", "6f", "6f", 
 "6c", "73", "b", "69", "65", "77", "65", "72", "2e", "68", "74", "6d", "6c"]
_

基本的に、単一のバックスラッシュは次の文字をエスケープするため、エスケープコンテキストに注意しないと、予期しない結果が生じます。

ソリューション:

ルックアップテーブルを使用すると、誤ってエスケープされた多くの文字が、印刷可能なASCII文字範囲_\x20-\x7F_の外側にある場合に復元できます。たとえば、上記の例では_12_または_\x0c12..toString(16)]は_'\\'+'v'_になります。

PS:情報の損失が発生し、コンテキスト情報またはメタ情報を通じて情報を復元しようとしていることに注意してください、つまり、この場合、文字列は印刷可能なASCIIの範囲にあります。

実装をコミュニティと共有してください。乾杯!

3
Lorenz Lo Sauer

「\\」は単一の\にエスケープされるため、変更がないため、「\\\\」で置き換える必要があります。

2
McAden