Как разобрать созданные в Word специальные символы в Java - PullRequest
3 голосов
/ 22 октября 2010

Я пытаюсь разобрать некоторые текстовые документы в Java. Некоторые значения - это, например, диапазон дат, и вместо того, чтобы показываться как Startdate - endDate, я получаю несколько прикольных символов, таких как

StartDate ΓÇô EndDate

Здесь слово вводит специальный символ hypen. Можете ли вы найти эти символы и заменить их обычными - или чем-то еще в строке, чтобы я мог затем разметить на «-» и что это за символ - ascii? Юникод или как?

Отредактировано, чтобы добавить код:

 String projDateString = "08/2010 ΓÇô Present"
                Charset charset = Charset.forName("Cp1252");
                CharsetDecoder decoder = charset.newDecoder();
                ByteBuffer buf = ByteBuffer.wrap(projDateString.getBytes("Cp1252"));
                CharBuffer cbuf = decoder.decode(buf); 
                String s = cbuf.toString();
                println ("S: " + s)

                println("projDatestring: " + projDateString)

Выводит следующее:

S: 08/2010 ΓÇô Present
projDatestring: 08/2010 ΓÇô Present

Кроме того, используя тот же projDateString выше, если я это сделаю:

projDateString.replaceAll("\u0096", "\u2013");
projDateString.replaceAll("\u0097", "\u2014");

, а затем распечатывает projDateString, он по-прежнему печатается как

projDatestring: 08/2010 ΓÇô Present

Ответы [ 4 ]

6 голосов
/ 23 октября 2010

Возможно, вы получаете Windows-1252, которая является набором символов, а не кодировкой.(Torgamus - поиск в Google для Windows-1232 мне ничего не дал.)

Windows-1252, ранее "Cp1252" - это почти Unicode, но содержит некоторые символы, которые пришли из Cp1252 в ихте же места. En Dash - это символ 150 (0x96), который попадает в диапазон зарезервированных управляющих символов Unicode C1 и не должен быть там.

Вы можете найти символ 150 и заменить его на\u2013, который является правильной кодовой точкой Unicode для En Dash.

Есть довольно много других символов, которые MS имеет в диапазоне от 0x80 до 0x9f, которые зарезервированы в стандарте Unicode, включая Em Dash, маркерыи их "умные" кавычки.


Редактировать: Кстати, Java использует значения кодовой точки Unicode для символов внутри.UTF-8 - это кодировка , которую Java использует в качестве кодировки по умолчанию при записи строк в файлы или сетевые подключения.


Скажем, у вас есть

String stuff = MSWordUtil.getNextChunkOfText();

Где MSWordUtil - это то, что вы написали, чтобы получить кусочки файла MS-Word .doc.Он может сводиться к

File myDocFile = new File(pathAndFileFromUser);
InputStream input = new FileInputStream(myDocFile);
// and then start reading chunks of the file

По умолчанию, когда вы считываете байтовые буферы из файла и делаете из них строки, Java будет обрабатывать его как кодированный в кодировке UTF-8.Как говорит лорд Торгамус, есть способы сообщить , какую кодировку следует использовать, но без этого Windows-1252 довольно близка к UTF-8, за исключением тех неприятных символов, которые находятся в элементе управления C1range.

После получения некоторой строки типа stuff и выше вы не найдете в ней \u2013 или \u2014, вместо этого вы найдете 0x96 и 0x97.

При этомТочка, которую вы должны быть в состоянии сделать

stuff.replaceAll("\u0096", "\u2013");

Я не делаю этого в моем коде, где мне пришлось иметь дело с этой проблемой.Я перебираю входные данные CharSequence по одному символу за раз, решаю, основываясь на 0x80 <= charValue <= 0x9f, нужно ли его заменить, и ищу в массиве, на что его заменить.Вышеуказанная метод replaceAll () намного проще, если все, что вас волнует, это 1252 En Dash против Unicode En Dash.

4 голосов
/ 19 июля 2012
s = s.replace( (char)145, (char)'\'');

s = s.replace( (char)8216, (char)'\''); // left single quote

s = s.replace( (char)146, (char)'\'');

s = s.replace( (char)8217, (char)'\''); // right single quote

s = s.replace( (char)147, (char)'\"');

s = s.replace( (char)148, (char)'\"');

s = s.replace( (char)8220, (char)'\"'); // left double

s = s.replace( (char)8221, (char)'\"'); // right double

s = s.replace( (char)8211, (char)'-' ); // em dash??    

s = s.replace( (char)150, (char)'-' );

http://www.coderanch.com/how-to/java/WeirdWordCharacters

2 голосов
/ 22 октября 2010

Ваша проблема почти наверняка связана с вашей схемой кодирования, не соответствующей схеме кодирования, в которой сохраняет Word. Ваш код, вероятно, использует Java по умолчанию, вероятно UTF-8 , если вы ничего не сделали дляЭто.С другой стороны, ваш ввод, вероятно, Windows-1252 , по умолчанию для документов Microsoft Word .doc.Смотрите этот сайт для получения дополнительной информации.В частности,

В Windows ISO-8859-1 заменяется Windows-1252, что часто означает, что текст, скопированный, скажем, из документа Microsoft Word и вставленный прямо в веб-страницу, производит проверку HTMLошибки.

Так что это значит для вас?Вы должны будете сообщить своей программе, что для ввода используется кодировка Windows-1252, и преобразовать ее в UTF-8.Вы можете сделать это в различных вариантах «вручную».Вероятно, наиболее естественным способом является использование встроенного в Java Charset класса .

Windows-1252 распознается Реестром Charset IANA

Имя: windows-1252
MIBenum: 2252
Источник: Microsoft (http://www.iana.org/assignments/charset-reg/windows-1252) [Wendt]
Псевдоним: Нет

, так что вы должны бытьCharset -совместимо. Я не делал этого раньше себя, поэтому я не могу дать вам пример кода, но я укажу, что есть конструктор String, который принимает byte[] и Charsetв качестве аргументов.

1 голос
/ 23 октября 2010

Вероятно, этот символ является en dash , и странная реклама, которую вы видите, связана с различием между способом, которым Word кодирует этот символ, и способом, которым этот символ декодируется любой (другой) системой, которую выиспользуют для его отображения.

Если я правильно помню, когда я немного поработал над кодировкой символов в Java, экземпляры String всегда внутренне используют UTF-8;таким образом, в таком случае вы можете искать и заменять один символ в форме Юникода.Например, предположим, что вы хотите заменить умные кавычки на простые двойные кавычки: при наличии String s вы можете написать

s = s.replace('\u201c', '"');
s = s.replace('\u201d', '"');

, где 201c и 201d - это кодовые точки Unicode дляоткрытие и закрытие умных цитат.Согласно ссылке выше в Википедии, кодовая точка Unicode для дефиса - 2013.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...