これが何と呼ばれているのかわかりませんので、検索に問題があります。 JavaScriptでhttp\u00253A\u00252F\u00252Fexample.com
からhttp://example.com
にUnicodeで文字列をデコードするにはどうすればよいですか? unescape
、decodeURI
、およびdecodeURIComponent
を試してみたので、残っているのは文字列の置換だけだと思います。
編集:文字列は入力されず、別のコードの部分文字列です。そのため、問題を解決するには、次のようなものから始める必要があります。
var s = 'http\\u00253A\\u00252F\\u00252Fexample.com';
Unescape()が機能しない理由を示すことを願っています。
元の回答:
unescape(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"'));
> 'http://example.com'
すべての作業をJSON.parse
にオフロードできます
編集(2017-10-12):
@MechaLynxと@ Kevin-Weberは、unescape()
はブラウザ以外の環境では非推奨であり、TypeScriptには存在しないことに注意してください。 decodeURIComponent
はドロップインの代替品です。互換性を広げるには、代わりに以下を使用してください。
decodeURIComponent(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"'));
> 'http://example.com'
UPDATE:これは、古いブラウザまたはブラウザ以外のプラットフォームに適用する必要があるソリューションであり、説明のために維持されていることに注意してください。最新の回答については、以下の@radicandの回答を参照してください。
これは、Unicodeのエスケープされた文字列です。最初に文字列がエスケープされ、次にユニコードでエンコードされました。通常に戻すには:
var x = "http\\u00253A\\u00252F\\u00252Fexample.com";
var r = /\\u([\d\w]{4})/gi;
x = x.replace(r, function (match, grp) {
return String.fromCharCode(parseInt(grp, 16)); } );
console.log(x); // http%3A%2F%2Fexample.com
x = unescape(x);
console.log(x); // http://example.com
説明するには:正規表現を使用して\u0025
を探します。ただし、置換操作にはこの文字列の一部しか必要ないため、括弧を使用して再利用する部分0025
を分離します。この分離された部分はグループと呼ばれます。
式の最後のgi
部分は、最初のインスタンスだけでなく、文字列内のすべてのインスタンスに一致する必要があること、および一致では大文字と小文字を区別しないことを示します。これは、例を考えれば不必要に見えるかもしれませんが、汎用性を追加します。
ここで、ある文字列から次の文字列に変換するには、各一致の各グループでいくつかのステップを実行する必要がありますが、文字列を変換するだけではできません。便利なことに、String.replace操作は、一致するたびに実行される関数を受け入れることができます。その関数の戻り値は、文字列内の一致自体を置き換えます。
この関数が受け入れる2番目のパラメーター(使用する必要があるグループ)を使用し、同等のutf-8シーケンスに変換してから、組み込みのunescape
関数を使用して文字列を適切な形式にデコードします。
unescape()
の使用は 非推奨 であり、たとえばTypeScriptコンパイラでは機能しないことに注意してください。
Radicandの回答と以下のコメントセクションに基づいて、更新されたソリューションを次に示します。
var string = "http\\u00253A\\u00252F\\u00252Fexample.com";
decodeURIComponent(JSON.parse('"' + string.replace(/\"/g, '\\"') + '"'));
http://example.com
私はこれを既存の回答へのコメントの下に置くのに十分な担当者がいません:
unescape
は、URI(またはエンコードされたutf-8)を扱う場合にのみ非推奨です。これはおそらくほとんどの人のニーズに当てはまります。 encodeURIComponent
はjs文字列をエスケープされたUTF-8に変換し、decodeURIComponent
はエスケープされたUTF-8バイトでのみ機能します。拡張ASCIIは有効なutf-8ではないため(これはまだUnicode値ですが)、decodeURIComponent('%a9'); // error
のように、unescape('%a9'); // ©
のようなエラーが発生します。
decodeURIComponentは、"%C2"
または0x7f
上の孤立したバイトでは動作しません。これは、utf-8ではサロゲートの一部を示すためです。ただし、decodeURIComponent("%C2%A9") //gives you ©
Unescapeはその// ©
で適切に機能せず、エラーをスローしません。そのため、データを知らない場合、unescapeはバグのあるコードにつながる可能性があります。
このページをご覧ください: http://www.rishida.net/tools/conversion/
コードを上部のテキストボックスに貼り付けます(最初に二重スラッシュを削除します)。
コードはオープンソースです: http://www.rishida.net/tools/conversion/conversionfunctions.js
このためにJSON.decode
を使用すると、次の重要な欠点があります。
JSON.decode
、\\n
、\n
、\\0
がすべて有効であっても、a"a
に次のいずれかを渡すとエラーになります。 [SOMECODE] _\\x45
\\u{045}
他にも注意点があります。基本的に、この目的でJSON.decode
を使用することはハックであり、常に期待する方法では機能しません。文字列操作ではなく、JSON
ライブラリを使用してJSONを処理する必要があります。
私は最近この問題に自分自身で遭遇し、堅牢なデコーダーを望んでいたので、自分で1つを書くことになりました。完全で完全にテストされており、こちらから入手できます: https://github.com/iansan5653/unraw 。 JavaScriptの標準を可能な限り模倣します。
ソースは約250行なので、ここにすべてを含めることはしませんが、基本的に次の正規表現を使用してすべてのエスケープシーケンスを検索し、parseInt(string, 16)
を使用して解析してbase-16番号をデコードし、String.fromCodePoint(number)
対応する文字を取得します。
/\\(?:(\\)|x([\s\S]{0,2})|u(\{[^}]*\}?)|u([\s\S]{4})\\u([^{][\s\S]{0,3})|u([\s\S]{0,4})|([0-3]?[0-7]{1,2})|([\s\S])|$)/g
コメント(注:この正規表現は、無効なものを含むすべてのエスケープシーケンスに一致します。文字列がJSでエラーをスローする場合、ライブラリでエラーがスローされます(つまり、'\x!!'
will error])。
/
\\ # All escape sequences start with a backslash
(?: # Starts a group of 'or' statements
(\\) # If a second backslash is encountered, stop there (it's an escaped slash)
| # or
x([\s\S]{0,2}) # Match valid hexadecimal sequences
| # or
u(\{[^}]*\}?) # Match valid code point sequences
| # or
u([\s\S]{4})\\u([^{][\s\S]{0,3}) # Match surrogate code points which get parsed together
| # or
u([\s\S]{0,4}) # Match non-surrogate Unicode sequences
| # or
([0-3]?[0-7]{1,2}) # Match deprecated octal sequences
| # or
([\s\S]) # Match anything else ('.' doesn't match newlines)
| # or
$ # Match the end of the string
) # End the group of 'or' statements
/g # Match as many instances as there are
そのライブラリの使用:
import unraw from "unraw";
let step1 = unraw('http\\u00253A\\u00252F\\u00252Fexample.com');
// yields "http%3A%2F%2Fexample.com"
// Then you can use decodeURIComponent to further decode it:
let step2 = decodeURIComponent(step1);
// yields http://example.com