1

Jericho HTML パーサーによって返され、ロシア語のテキストを含む文字列があります。それぞれの HTML ファイルのヘッダーによるsource.getEncoding()と、エンコーディングは Windows-1251 です。

この文字列を読み取り可能なものに変換するにはどうすればよいですか?

私はこれを試しました:

import java.io.UnsupportedEncodingException;

public class Program {
    public void run() throws UnsupportedEncodingException {
        final String windows1251String = getWindows1251String();
        System.out.println("String (Windows-1251): " + windows1251String);
        final String readableString = convertString(windows1251String);
        System.out.println("String (converted): " + readableString);
    }
    private String convertString(String windows1251String) throws UnsupportedEncodingException {
        return new String(windows1251String.getBytes(), "UTF-8");
    }
    private String getWindows1251String() {
        final byte[] bytes = new byte[] {32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32};
        return new String(bytes);
    }
    public static void main(final String[] args) throws UnsupportedEncodingException {
        final Program program = new Program();
        program.run();
    }
}

変数bytesには、デバッガーに表示されるデータが含まれています。これはnet.htmlparser.jericho.Element.getContent().toString().getBytes(). ここにその配列をコピーして貼り付けただけです。

これは機能しません -readableStringゴミが含まれています。

Windows-1251 文字列が正しくデコードされていることを確認するにはどうすればよいですか?

更新 1 (2015 年 7 月 30 日 12:45 MSK):の呼び出しでエンコーディングを変更しconvertStringWindows-1251も、何も変わりません。以下のスクリーンショットを参照してください。

スクリーンショット

更新 2:別の試み:

2 番目のスクリーンショット

更新 3 (2015 年 7 月 30 日 14:38):デコードする必要があるテキストは、以下に示すドロップダウン リストのテキストに対応しています。

期待される結果

更新 4 (30.07.2015 14:41):エンコーディング検出器 (コードは以下を参照) は、エンコーディングがWindows-1251ではなくUTF-8.

public static String guessEncoding(byte[] bytes) {
    String DEFAULT_ENCODING = "UTF-8";
    org.mozilla.universalchardet.UniversalDetector detector =
        new org.mozilla.universalchardet.UniversalDetector(null);
    detector.handleData(bytes, 0, bytes.length);
    detector.dataEnd();
    String encoding = detector.getDetectedCharset();
    System.out.println("Detected encoding: " + encoding);
    detector.reset();
    if (encoding == null) {
        encoding = DEFAULT_ENCODING;
    }
    return encoding;
}
4

3 に答える 3

3

(更新に照らして、元の回答を削除し、最初からやり直しました)

登場するテキスト

пїЅпїЅпїЅпїЅпїЅпїЅ

これらのバイト値の正確なデコードです

-17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67

(いずれかの端にスペースである 32 が埋め込まれます。)

だからどちらか

1) テキストがゴミである、または

2)テキストはそのように見えるはずですまたは

3) エンコーディングが Windows-1215 ではない

この行は著しく間違っています

return new String(windows1251String.getBytes(), "UTF-8");

文字列からバイトを抽出し、そこから新しい文字列を構築することは、エンコーディング間で「変換」する方法ではありません。入力文字列と出力文字列の両方が、内部で UTF-16 エンコーディングを使用します (通常、それを知ったり気にしたりする必要はありません)。他のエンコーディングが有効になるのは、テキスト データが文字列オブジェクトの外部 (つまり、初期バイト配列) に格納されている場合のみです。変換は、文字列が構築されてから完了するときに発生します。ある String 型から別の String 型への変換はありません。それらはすべて同じです。

これが

return new String(bytes);

これと同じことをします

return new String(bytes, "Windows-1251");

Windows-1251 がプラットフォームのデフォルトのエンコーディングであることを示唆しています。(これは、MSK であるタイムゾーンによってさらにサポートされます)

于 2015-07-30T11:02:31.503 に答える
3

Web サイトからテキストを読み取るコードを修正することで、この問題を解決しました。

private String readContent(final String urlAsString) {
    final StringBuilder content = new StringBuilder();
    BufferedReader reader = null;
    InputStream inputStream = null;
    try {
        final URL url = new URL(urlAsString);
        inputStream = url.openStream();
        reader =
            new BufferedReader(new InputStreamReader(inputStream);

        String inputLine;
        while ((inputLine = reader.readLine()) != null) {
            content.append(inputLine);
        }
    } catch (final IOException exception) {
        exception.printStackTrace();
    } finally {
        IOUtils.closeQuietly(reader);
        IOUtils.closeQuietly(inputStream);
    }
    return content.toString();
}

ラインを変えました

new BufferedReader(new InputStreamReader(inputStream);

new BufferedReader(new InputStreamReader(inputStream, "Windows-1251"));

そしてそれはうまくいきました。

于 2015-07-30T12:33:03.287 に答える