Что лучший способ состоит в том, чтобы преобразовать строку от Unicode до ASCII, не изменяя, это - длина (который очень важен в моем случае)? Также символы без любых проблем преобразования должны быть в тех же позициях как в исходной строке. Таким образом, "Ä" должен быть преобразован в "A" и не что-то загадочное, которое имеет больше символов.
Править:
@novalis - Такие символы (например, азиатских языков) должны просто быть преобразованы в некоторых заполнителей. Я не также интересуюсь теми словами или что они имеют в виду.
@MtnViewMark - Я должен сохранить количество всех символов и положение ASCII доступные символы при любом обстоятельстве.
Здесь еще некоторая информация: у Меня есть некоторые инструменты анализа текста, которые могут только обработать строки ASCII. Большая часть текста, который должен быть обработан, находится на английском языке, но некоторые содержат не символы ASCII. Я не интересуюсь теми словами, но я должен быть уверен, что слова, которыми я интересуюсь (те, которые только содержат символы ASCII) в тех же положениях после преобразования строк.
Как указано в Это Ответ, следующий код должен Работа:
String s = "口水雞 hello Ä";
String s1 = Normalizer.normalize(s, Normalizer.Form.NFKD);
String regex = "[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+";
String s2 = new String(s1.replaceAll(regex, "").getBytes("ascii"), "ascii");
System.out.println(s2);
System.out.println(s.length() == s2.length());
Выход
??? hello A
true
, поэтому сначала вы удалите диабристы, преобразующие в ASCII. Символы без ASCII станут вопросительными знаками.
Не видя вашего кода, я не могу быть уверен. Однако пытались ли вы поместить зеленые элементы в тэги и пометить их как четкие: оба;? Это может переместить их в 3-й ряд. Это то, что вы должны проверить.
-121--4716542-Вот еще один способ, который использует 2-элементный конструктор данных. Для его инициализации не требуется никаких функций. Нет кода третьей стороны (Boost), нет статических функций или объектов, нет трюков, просто C++:
#include <map>
#include <string>
typedef std::map<std::string, int> MyMap;
const MyMap::value_type rawData[] = {
MyMap::value_type("hello", 42),
MyMap::value_type("world", 88),
};
const int numElems = sizeof rawData / sizeof rawData[0];
MyMap myMap(rawData, rawData + numElems);
Так как я написал этот ответ C++ 11 вышел. Теперь можно непосредственно инициализировать контейнеры STL с помощью новой функции перечислять инициализатора:
const MyMap myMap = { {"hello", 42}, {"world", 88} };
-121-2005776- Используйте java.text.Normalizer.normalize ()
с помощью Normalizer.Form.NFD
, а затем отфильтруйте символы, не относящиеся к ASCII.
Предостережение: я не знаю Java. Немного о наборах символов.
Вы не указываете, какой именно набор символов вы используете.
Но независимо от того, что вы используете, невозможно преобразовать строку Unicode в ASCII и сохранить исходную длину и позиции символов просто потому, что набор символов Unicode будет использовать несколько байтов для некоторых символов (очевидно) .
Единственное известное мне исключение - это строка UTF-8, содержащая только символы ASCII: эта строка уже будет идентична как в UTF-8, так и в ASCII, потому что UTF-8 использует многобайтовые символы только при необходимости. (Я не знаю о других вариантах Unicode, могут быть другие динамические).
Единственный обходной путь, который я вижу, - это добавление пробела к любому специальному символу, который был заменен символом ASCII, но это испортит строку ( Göteborg
в UTF8 должно было стать Go теборг
, чтобы сохранить длину).
Может быть, вы хотите уточнить, чего вы хотите / должны достичь, чтобы люди здесь могли предложить обходные пути.
Одна из проблем с Нормализатором заключается в том, что до Java 1.6 он находится в пакете sun.text, тогда как в 1.6 он находится в пакете java.text, и его подпись метода изменилась. Поэтому, если ваше приложение должно работать на обеих платформах, вам придется использовать отражение.
Альтернативное индивидуальное решение описано как techniwue 3 здесь