Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > кириллица


Автор: virin 6.6.2005, 10:09
Подскажите, плиз, начинающему:
Как преобразовать Unicode вида р в нормальные русские буквы?

Автор: batigoal 6.6.2005, 10:21
Где именно? В документе, в программе?

Автор: virin 6.6.2005, 10:27
в JTextPane, с которым ассоциируется HTMLDocument

Автор: mixture 16.7.2005, 12:56
Сам столгнулся с этой ужастью.
После длительного рытья в исходниках javax.swing.text.html.*

Обнаружил вот такое (HTMLWriter):

Код

/**
     * This method is overriden to map any character entities, such as
     * &lt; to &amp;lt;. <code>super.output</code> will be invoked to
     * write the content.
     */
    protected void output(char[] chars, int start, int length)
               throws IOException {
    if (!replaceEntities) {
        super.output(chars, start, length);
        return;
    }
    int last = start;
    length += start;
    for (int counter = start; counter < length; counter++) {
        // This will change, we need better support character level
        // entities.
        switch(chars[counter]) {
        // Character level entities.
        case '<':
        if (counter > last) {
            super.output(chars, last, counter - last);
        }
        last = counter + 1;
        output("&lt;");
        break;
        case '>':
        if (counter > last) {
            super.output(chars, last, counter - last);
        }
        last = counter + 1;
        output("&gt;");
        break;
        case '&':
        if (counter > last) {
            super.output(chars, last, counter - last);
        }
        last = counter + 1;
        output("&amp;");
        break;
        case '"':
        if (counter > last) {
            super.output(chars, last, counter - last);
        }
        last = counter + 1;
        output("&quot;");
        break;
        // Special characters
        case '\n':
        case '\t':
        case '\r':
        break;
        [b]default:
        if (chars[counter] < ' ' || chars[counter] > 127) {
            if (counter > last) {
            super.output(chars, last, counter - last);
            }
            last = counter + 1;
            // If the character is outside of ascii, write the
            // numeric value.
            output("&#");
            output(String.valueOf((int)chars[counter]));
            output(";");
        }
        break;[/b]
        }
    }
    if (last < length) {
        super.output(chars, last, length - last);
    }
    }



В простейшем случае, решение может выглядеть так (мне этого хватило):

Код

   public static String getPlainUnicodePlease(String s) {
        StringBuffer buf = new StringBuffer();
        int i;
        for (i=0; i < s.length(); ++i) {
            char ch = s.charAt(i);
            if (ch == '&') {
                int cln = s.indexOf(';', i + 1);
                if (cln == -1) {
                    buf.append(ch);
                    continue;
                }
                String entry = s.substring(i + 1, cln);
                if (entry.charAt(0) == '#') {
                    buf.append((char)(Integer.valueOf(entry.substring(1)).intValue()));
                }
                else {
                    buf.append("&" + entry + ";");
                }
                i = cln;
            }
            else {
                buf.append(ch);
            }
        }
        return buf.toString();
    }


Для &amp нужно заводить отдельный мап чарактеров.

Автор: batigoal 16.7.2005, 12:58
Думается мне, что есть другой способ, кроме изменения исходников smile

Автор: mixture 16.7.2005, 13:20
Никакое это не изменение.

делается это так

String s = getPlainUnicodePlease(jMyTextPane.getText());

Можно было бы конечно унаследоваться от HTMLWRiter, скопировать часть исходников, где нет оцифрения юникодов и переопределить метод output, однако HTMLEditorKit и не позволяет просто так использовать свой Writer.

JTextPane

Код

   public String getText() {
    String txt;
    try {
        StringWriter buf = new StringWriter();
        write(buf);
        txt = buf.toString();
        } catch (IOException ioe) {
            txt = null;
        }
        return txt;
    }


JTexTComponent

Код

    public void write(Writer out) throws IOException {
        Document doc = getDocument();
        try {
            getUI().getEditorKit(this).write(out, doc, 0, doc.getLength());
        } catch (BadLocationException e) {
            throw new IOException(e.getMessage());
        }
    }


HTMLEditorKit
Код


   public void write(Writer out, Document doc, int pos, int len) 
    throws IOException, BadLocationException {

    if (doc instanceof HTMLDocument) {
        HTMLWriter w = new [b]HTMLWriter[/b](out, (HTMLDocument)doc, pos, len);
        w.write();
    } else if (doc instanceof StyledDocument) {
        MinimalHTMLWriter w = new MinimalHTMLWriter(out, (StyledDocument)doc, pos, len);
        w.write();
    } else {
        super.write(out, doc, pos, len);
    }
    }


Нужно HTMLEditorKit тоже наследовать.

Хотя, не получится. Методы дедушек не достанешь, область видимости свойств не поменяешь smile

Автор: Гость_Sleepy_PIP 17.7.2005, 20:47
вот. и я попал.
есть простейшая String, содержащая
"ftp%3A%2F%2F194.67.139.192%2FCD+3D+%EC%EE%E4%E5%EB%E8+2000"
надо это хоз-во перевести к виду:
"ftp://194.67.139.192/CD 3D модели 2000"
честно скажу - 40 мин. копался - не понимаю. устал? ну может быть.
но я даже не понимаю как получить список допустимых чарсетов в java.nio.charset.Charset!
Еще раз - речь идет о преобразовании одной строки - в другую ... элементарном.

пробел тут у меня боооольшой. не понимаю smile.

Автор: Sleepy_PIP 17.7.2005, 22:02
это не гость. это Sleepy_PIP smile

Автор: tux 18.7.2005, 03:44
Декодирование URL:
Код

import java.net.URLDecoder;
...
String str = URLDecoder.decode("ftp%3A%2F%2F194.67.139.192%2FCD+3D+%EC%EE%E4%E5%EB%E8+2000", "CP1251");

Список доступных кодировок:
Код

import java.nio.charset.Charset;
...
Set charsets = Charset.availableCharsets().keySet();

Автор: Sleepy_PIP 18.7.2005, 11:06
Цитата(tux @ 18.7.2005, 03:44)
Декодирование URL:
Код

import java.net.URLDecoder;
...
String str = URLDecoder.decode("ftp%3A%2F%2F194.67.139.192%2FCD+3D+%EC%EE%E4%E5%EB%E8+2000", "CP1251");

Список доступных кодировок:
Код

import java.nio.charset.Charset;
...
Set charsets = Charset.availableCharsets().keySet();

ага. с URL понятно. Спасибо большое! а в общем случае - как конвертировать строки между чарсетами?
Спасибо!

Автор: tux 18.7.2005, 11:21
Вообще говоря, конвертирование строк нужно только если в JVM поступает что-то извне (например, из файлов читается или по сети передается), все строки в Java хранятся в Юникоде. Для потоков ввода-вывода есть такая возможность:
  • при чтении из входного потока можно использовать класс java.io.InputStreamReader, у которого есть такой конструктор - InputStreamReader(InputStream in, Charset cs). Здесь cs - кодировка, в которой передаются байты входного потока.
  • при записи в выходной поток можно использовать класс java.io.OutputStreamWriter, который может декодировать данные в обратную сторону.
Есть еще такая пара классов - java.nio.charset.CharsetDecoder и java.nio.charset.CharsetEncoder, которые предназначены для преобразования массива байтов в массив символов и наоборот, но с ними не работал и принципов использования не знаю.

Автор: 3,14 19.7.2005, 12:09
По-моему при преобразовании в Unicode и обратно удобнее пользоваться просто String-ами.

Преобразовать в String:
Код

new String(bytes, "windows-1251");


Получить байты в нужной кодировке тоже не проблема:
Код

myStr.getBytes("windows-1251");

Автор: tux 19.7.2005, 12:22
Цитата
По-моему при преобразовании в Unicode и обратно удобнее пользоваться просто String-ами.

Однако, тогда нужно иметь уже готовый массив байтов, что не всегда достижимо. Впрочем, часто действительно удобнее, не зря ведь такую возможность предусматривали. smile

Автор: Dibazzol 16.7.2007, 17:35
А подскажите пожалуйста!
Есть метод, я уже в нем поменять умудрился каждую букву, все равно ничего не выходит:
Код

 public void readAndParse(String key) {
    try {
      int c = 0;
      int t = 0;
      boolean ready = false;
      String code;
      GlobalString1 = "";
      KeyQuant = "";
      //String key=new String();
      String data = "text=" + key;
      URL url = new URL("http://direct.yandex.ru/stat/wordsstat.pl?checkboxes=&rpt=ppc&shw=1&text=&key=&tm=");
      HttpURLConnection con = (HttpURLConnection) url.openConnection();
      con.setRequestMethod("POST");
      con.setDoOutput(true);
      con.setDoInput(true);
      OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
      wr.write(data);
      wr.flush();
      InputStreamReader Inp = new InputStreamReader(con.getInputStream());
      String Ink = Inp.getEncoding();
      
      BufferedReader is = new BufferedReader(Inp);
      String line;
      String count = new String();
      while ( (line = is.readLine()) != null) {
        byte[] b = line.getBytes("UTF-16");
        line = new String (b,"Cp1251");
        GlobalString1 += line;
//System.out.println(System.getProperty("file.encoding"));
      }
     System.out.println(GlobalString1);
      // byte[] b = GlobalString1.getBytes("UTF-8");
      //  String d=new String(b);
      // GlobalString1=d;
      int k = GlobalString1.length() - 50;
      //System.out.println("mba"+k);
      //System.out.println(GlobalString1);

      for (int i = 1; i < k; i++) {
        //System.out.println(i);
        if (ready == false) {
          if (GlobalString1.substring(i, k).startsWith(key + "</a></td>")) {
            System.out.println("YES");
            for (int j = i + key.length() + 27; j < k; j++) {
              if (GlobalString1.substring(j, k).startsWith("</td>")) {
                KeyQuant += GlobalString1.substring(i + key.length() + 27, j);
                System.out.println("keyquant" + KeyQuant);
                i = j;
                ready = true;
                break;
              }
            }
          }
        }
        else break;
      }

Им я пытаюсь получить у яндекс.директ ключевые слова для поиска.

С английскими словами все отлично получается, несмотря на кривость написания, а вот что делать с русскими, я не могу понять. ответ сервера получается в некоторой странной кодировке, где все, что на англ. читабельно, а на русском - нет. В связи с этим, метод ничего не может найти.
Я перепробовал уже все возможные кодировки. Что посоветуете?

Добавлено через 2 минуты и 15 секунд
Может быть стоит просто запрос key перевести в урл формат?

Добавлено через 7 минут и 41 секунду
АА!! все получилось, в очередной раз респекты LSD!
http://forum.vingrad.ru/topic-112179.html

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)