4 に答える
これを行う標準ライブラリに正規化ルーチンがあるかどうかはわかりません。「スマートな」引用符の変換が標準のUnicode 正規化ルーチンによって処理されるとは思いませんが、引用しないでください。
賢明なことは、ISO-8859-1をダンプして を使い始めることUTF-8
です。つまり、通常許可されている Unicode コード ポイントを としてエンコードされた HTML ページにエンコードすることは可能ISO-8859-1
です。次に示すように、エスケープ シーケンスを使用してエンコードできます。
public final class HtmlEncoder {
private HtmlEncoder() {}
public static <T extends Appendable> T escapeNonLatin(CharSequence sequence,
T out) throws java.io.IOException {
for (int i = 0; i < sequence.length(); i++) {
char ch = sequence.charAt(i);
if (Character.UnicodeBlock.of(ch) == Character.UnicodeBlock.BASIC_LATIN) {
out.append(ch);
} else {
int codepoint = Character.codePointAt(sequence, i);
// handle supplementary range chars
i += Character.charCount(codepoint) - 1;
// emit entity
out.append("&#x");
out.append(Integer.toHexString(codepoint));
out.append(";");
}
}
return out;
}
}
使用例:
String foo = "This is Cyrillic Ya: \u044F\n"
+ "This is fraktur G: \uD835\uDD0A\n" + "This is a smart quote: \u201C";
StringBuilder sb = HtmlEncoder.escapeNonLatin(foo, new StringBuilder());
System.out.println(sb.toString());
上記では、文字の左二重引用符 ( U+201C
“ ) は “ としてエンコードされます。他のいくつかの任意のコード ポイントも同様にエンコードされます。
このアプローチには注意が必要です。テキストを HTML 用にエスケープする必要がある場合は、上記のコードまたはアンパサンドがエスケープされる前に行う必要があります。
デフォルトのエンコーディングによっては、次の行で問題が発生する可能性があります。
byte[] latin1 = sb.toString().getBytes("ISO-8859-1");
return new String(latin1);
Javaでは、String/Charは常にUTF-16BEです。異なるエンコーディングは、文字をバイトに変換する場合にのみ関係します。デフォルトのエンコーディングがUTF-8であるとすると、latin1
バッファはUTF-8として扱われ、Latin-1の一部のシーケンスが無効なUTF-8シーケンスを形成する可能性があり、?が表示されます。
String オブジェクトをインスタンス化するときは、使用するエンコーディングを指定する必要があります。
だから置き換えます:
return new String(latin1);
に
return new String(latin1, "ISO-8859-1");