3

これと同様の質問がStackOverflowで行われていますが、正確にはこれではありません。最も近いのは、おそらく「ユニコード文字列をASCIIに変換するjavascript」であり、「これは重複している必要があります」というコメントがすでにあります。似たような投稿をいくつか読んだことがありますが、私の特定の質問には答えていません。私は非常に優れたW3Schoolsサイトを調べ、Googleでも検索しましたが、その方法でも答えは見つかりませんでした。したがって、ここでのヒントは非常に重要です。感謝。)


JavaScriptの一部に渡されるバイトの配列があります。JavaScriptでは、データは文字列で到着します。サードパーティのアプリケーションからのものであるため、転送のメカニズムがわかりません。文字列が「広い」か「狭い」かはわかりません。

私のJavaScriptには、のようなコードがありますb = str.charCodeAt(pos);

私の問題は、0x86=134などのバイト値が文字0x2020=8224として送信されていることです。これは、元のバイトがラテン1(おそらく)の「短剣」文字として解釈され、同等のUnicodeコードポイント。(問題はJavaScriptの「障害」である場合とそうでない場合があります。)0x00..0x7Fと0xA0..0xFFの範囲は問題ないように見えますが、他の値でも同様の問題が発生しますが、0x80..0x9Fのほとんどの値が影響を受けます。いずれの場合も、値は元のLatin-1のUnicodeのようです。

もう1つの観察結果は、文字列の長さが、長さがバイト単位で測定された場合に狭い文字列に期待する長さであるということです。(一方、lengthが抽象文字で値を返す場合、これは何も教えてくれません。)

したがって、JavaScriptでは、文字列の「raw」バイトを取得する方法、Latin-1またはASCII文字コードを直接取得する方法、文字エンコーディング間で変換する方法、またはデフォルトのエンコーディングを定義する方法はありますか?

独自のマッピングを作成することはできますが、作成したくありません。それが私がやることになると思いますが、それは応急修理に応急修理をしているような感覚があります。

また、呼び出し元のアプリケーションで調整できるものがあるかどうかも調べています(データを幅の広い文字列として渡す可能性があるためですが、疑わしいと思います)。

いずれにせよ、私は単純なJavaScriptソリューションがあるかどうか、またはなぜないのかを理解することに興味があります。

(受信データが文字データの場合、Unicodeを自動的に処理するのは素晴らしいことです。しかし、そうではなく、単なるバイナリデータストリームです。)

ありがとう。

4

2 に答える 2

6

文字列には生のバイトのようなものはありません。EcmaScript仕様では、文字列をUTF-16コードユニットのシーケンスとして定義しています。これは、通訳者がこれまでに遭遇した中で最もきめ細かい表現です。

ブラウザにはエンコーディングライブラリはありません。バイト配列を文字列として表現しようとしていて、それを再エンコードしたい場合は、自分でロールする必要があります。

charCodeAt文字列がすでに有効なASCIIである場合は、メソッドを使用してコードユニットの数値を取得できます。

"\n".charCodeAt(0) === 10
于 2011-01-29T01:31:21.330 に答える
3

Javascript(Ecmascript)の仕様から始めます:http ://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf 。言う:

8.4文字列型 文字列型は、0個以上の16ビット符号なし整数値(「要素」)のすべての有限順序シーケンスのセットです。文字列型は通常、実行中のECMAScriptプログラムのテキストデータを表すために使用されます。この場合、文字列の各要素はコードユニット値として扱われます(第6節を参照)。各要素は、シーケンス内の位置を占めていると見なされます。これらの位置は、非負の整数でインデックス付けされます。最初の要素(存在する場合)は位置0にあり、次の要素(存在する場合)は位置1にあります。文字列の長さは、文字列内の要素(つまり、16ビット値)の数です。空の文字列の長さはゼロであるため、要素は含まれていません。

文字列に実際のテキストデータが含まれている場合、各要素は単一のUTF-16コードユニットと見なされます。これが文字列の実際のストレージ形式であるかどうかに関係なく、文字列内の文字は、UTF-16を使用して表されているかのように、初期のコード単位要素の位置によって番号が付けられます。文字列に対するすべての操作(特に明記されていない限り)は、文字列を未分化の16ビット符号なし整数のシーケンスとして扱います。結果の文字列が正規化された形式であることを保証するものでも、言語に依存する結果を保証するものでもありません。

注この設計の背後にある理論的根拠は、文字列の実装を可能な限りシンプルで高性能に保つことでした。目的は、実行環境に外部から入ってくるテキストデータ(たとえば、ユーザー入力、ファイルから読み取られたテキスト、またはネットワーク経由で受信されたテキストなど)を、実行中のプログラムが認識する前にUnicode正規化フォームCに変換することです。通常、これは、着信テキストが元の文字エンコードからUnicodeに変換されると同時に発生します(追加のオーバーヘッドは発生しません)。ECMAScriptソースコードは正規化された形式Cであることが推奨されるため、Unicodeエスケープシーケンスが含まれていない限り、文字列リテラルは正規化されることが保証されます(ソーステキストが正規化されることが保証されている場合)。

charCodeAt(pが提供するのは、文字列のインデックスp)にある文字のUTF-16値(16ビット数)です。UTF-16はUnicodeの基本多言語面(つまりコードポイント–および– )を直接表すため、Latin-1文字は期待する値である必要があります。U+0000U+D7FFU+E000U+FFFF

それらがインバウンドの3番目のオクテットストリームにエンコードの問題があることを私に示唆していないという事実— UTF-16への変換が行われていて、インバウンドのオクテットストリームのエンコードが間違っている場合、奇妙な結果が得られます。

おそらく、実際にはUTF-8(またはその逆)であるにもかかわらず、バニラASCIIとして扱われている可能性があります。UTF-8は、0x7Fを超えるコードポイントを2、3、または4オ​​クテットの「有向グラフ」として表します。

于 2011-01-29T01:39:42.800 に答える