Еще один подход к возврату значения из асинхронной функции - передать объект, который сохранит результат от асинхронной функции.
Вот пример того же:
var async = require("async");
// This wires up result back to the caller
var result = {};
var asyncTasks = [];
asyncTasks.push(function(_callback){
// some asynchronous operation
$.ajax({
url: '...',
success: function(response) {
result.response = response;
_callback();
}
});
});
async.parallel(asyncTasks, function(){
// result is available after performing asynchronous operation
console.log(result)
console.log('Done');
});
Я использую объект result
для хранения значения во время асинхронной операции. Это позволяет получить результат даже после асинхронного задания.
Я использую этот подход много. Мне было бы интересно узнать, насколько хорошо этот подход работает, когда задействован результат обратно через последовательные модули.
Используйте java.text.Normalizer
, чтобы обработать это для вас.
string = Normalizer.normalize(string, Normalizer.Form.NFD);
Это отделит все знаки акцента от символов. Затем вам просто нужно сравнить каждого персонажа с буквой и выбросить те, которые не являются.
string = string.replaceAll("[^\\p{ASCII}]", "");
Если ваш текст находится в юникоде, вы должны использовать это вместо:
string = string.replaceAll("\\p{M}", "");
Для юникода \\P{M}
соответствует базовому глифу, а \\p{M}
(нижний регистр) соответствует каждому акценту.
Благодаря GarretWilson для указателя и regular-expressions.info для большого руководства по юникоду.
Решение @ virgo47 очень быстрое, но приблизительное. В принятом ответе используется Normalizer и регулярное выражение. Я задавался вопросом, какая часть времени была занята Normalizer по сравнению с регулярным выражением, так как удаление всех символов, отличных от ASCII, может выполняться без регулярного выражения:
import java.text.Normalizer;
public class Strip {
public static String flattenToAscii(String string) {
StringBuilder sb = new StringBuilder(string.length());
string = Normalizer.normalize(string, Normalizer.Form.NFD);
for (char c : string.toCharArray()) {
if (c <= '\u007F') sb.append(c);
}
return sb.toString();
}
}
Небольшие дополнительные ускорения могут быть получены путем записывая в char [], а не вызывая toCharArray (), хотя я не уверен, что уменьшение ясности кода заслуживает этого:
public static String flattenToAscii(String string) {
char[] out = new char[string.length()];
string = Normalizer.normalize(string, Normalizer.Form.NFD);
int j = 0;
for (int i = 0, n = string.length(); i < n; ++i) {
char c = string.charAt(i);
if (c <= '\u007F') out[j++] = c;
}
return new String(out);
}
У этого варианта есть преимущество правильности той, которая используется Нормализатор и часть скорости, используемой таблицей. На моей машине это примерно в 4 раза быстрее, чем принятый ответ, а от 6,6 до 7 раз медленнее, чем @ virgo47 (принятый ответ примерно на 26 раз медленнее, чем @ virgo47 на моей машине).
С 2011 года вы можете использовать Apache Commons StringUtils.stripAccents (input) (начиная с 3.0):
String input = StringUtils.stripAccents("Tĥïŝ ĩš â fůňķŷ Šťŕĭńġ");
System.out.println(input);
// Prints "This is a funky String"
Примечание:
ответ (Erick Robertson's) не работает для Ø или Ł. Apache Commons 3.5 тоже не работает для Ø, но он работает для Ł. Прочитав статью Wikipedia для Ø , я не уверен, что ее следует заменить на «O»: это отдельное письмо на норвежском и датском языках, в алфавитном порядке после «z». Это хороший пример ограничений подхода «стриптиз-акцентов».
В зависимости от языка эти могут не считаться акцентами (которые изменяют звук буквы), но диакритические метки
https://en.wikipedia.org/wiki/Diacritic #Languages_with_letters_containing_diacritics
«Боснийский и хорватский имеют символы č, ć, đ, š и ž, которые считаются отдельными буквами и перечислены как таковые в словарях и других контекстах, в которых указаны слова в соответствии с алфавитным порядком ».
Удаление их может по своей сути изменить значение слова или изменить буквы на совершенно разные.
System.out.println(Normalizer.normalize("àèé", Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", ""));
работал для меня. Вывод фрагмента выше дает «aee», который я хотел, но
System.out.println(Normalizer.normalize("àèé", Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", ""));
не выполнял никакой замены.
Я предлагаю Junidecode . Он будет обрабатывать не только «Ł» и «Ø», но также хорошо подходит для переписывания из других алфавитов, таких как китайский, в латинский алфавит.
Решение @David Conrad - это самое быстрое, что я пытался использовать Normalizer, но у него есть ошибка. Он в основном разделяет символы, которые не являются акцентами, например, китайские иероглифы и другие буквы, такие как æ, все лишены. Символы, которые мы хотим разбить, - это метки интервалов, символы, которые не занимают дополнительной ширины в финальной строке. Эти символы нулевой ширины в основном объединяются в какой-то другой символ. Если вы можете видеть их изолированными как символ, например, как это, я полагаю, что он сочетается с символом пробела.
public static String flattenToAscii(String string) {
char[] out = new char[string.length()];
String norm = Normalizer.normalize(string, Normalizer.Form.NFD);
int j = 0;
for (int i = 0, n = norm.length(); i < n; ++i) {
char c = norm.charAt(i);
int type = Character.getType(c);
//Log.d(TAG,""+c);
//by Ricardo, modified the character check for accents, ref: http://stackoverflow.com/a/5697575/689223
if (type != Character.NON_SPACING_MARK){
out[j] = c;
j++;
}
}
//Log.d(TAG,"normalized string:"+norm+"/"+new String(out));
return new String(out);
}
EDIT: Если вы не застряли с Java & lt; 6, и скорость не является критичной, и / или таблица перевода слишком ограничена, используйте ответ Дэвида. Дело в том, чтобы использовать Normalizer
(введенный в Java 6) вместо таблицы перевода внутри цикла.
Хотя это не «идеальное» решение, оно хорошо работает, когда вы знаете диапазон (в нашем случае Latin1,2), работал до Java 6 (но это не настоящая проблема) и намного быстрее, чем самая рекомендуемая версия (может и не быть проблемой):
/**
* Mirror of the unicode table from 00c0 to 017f without diacritics.
*/
private static final String tab00c0 = "AAAAAAACEEEEIIII" +
"DNOOOOO\u00d7\u00d8UUUUYI\u00df" +
"aaaaaaaceeeeiiii" +
"\u00f0nooooo\u00f7\u00f8uuuuy\u00fey" +
"AaAaAaCcCcCcCcDd" +
"DdEeEeEeEeEeGgGg" +
"GgGgHhHhIiIiIiIi" +
"IiJjJjKkkLlLlLlL" +
"lLlNnNnNnnNnOoOo" +
"OoOoRrRrRrSsSsSs" +
"SsTtTtTtUuUuUuUu" +
"UuUuWwYyYZzZzZzF";
/**
* Returns string without diacritics - 7 bit approximation.
*
* @param source string to convert
* @return corresponding string without diacritics
*/
public static String removeDiacritic(String source) {
char[] vysl = new char[source.length()];
char one;
for (int i = 0; i < source.length(); i++) {
one = source.charAt(i);
if (one >= '\u00c0' && one <= '\u017f') {
one = tab00c0.charAt((int) one - '\u00c0');
}
vysl[i] = one;
}
return new String(vysl);
}
Тесты на моем HW с 32-битный JDK показывает, что он выполняет преобразование из aeelstc89FDČ в aeelstc89FDC 1 миллион раз в ~ 100 мс, в то время как способ Normalizer делает его в 3.7s (37x медленнее).
Наслаждайтесь: -)
Наслаждайтесь: -) Наслаждайтесь: -)Я столкнулся с той же проблемой, связанной с проверкой равенства строк. Одна из строк сравнения имеет код символа ASCII 128-255 .
, т. е. неразрывная space - [Hex - A0] Space [Hex - 20]. Показать Неразрывное пространство над HTML. Я использовал следующий
spacing entities
. Их характер и его байты похожи на&emsp is very wide space[ ]{-30, -128, -125}, &ensp is somewhat wide space[ ]{-30, -128, -126}, &thinsp is narrow space[ ]{32} , Non HTML Space {}
String s1 = "My Sample Space Data", s2 = "My Sample Space Data"; System.out.format("S1: %s\n", java.util.Arrays.toString(s1.getBytes())); System.out.format("S2: %s\n", java.util.Arrays.toString(s2.getBytes()));
Выход в байтах:
S1: [77, 121,
blockquote>32
, 83, 97, 109, 112, 108, 101,32
, 83, 112, 97, 99, 101,32
, 68, 97, 116, 97] S2: [ 77, 121,-30, -128, -125
, 83, 97, 109, 112, 108, 101,-30, -128, -125
, 83, 112, 97, 99, 101,-30, -128, -125
, 68, 97, 116, 97]Используйте следующий код для разных пространств и их байтовых кодов:
wiki for List_of_Unicode_characters
String spacing_entities = "very wide space,narrow space,regular space,invisible separator"; System.out.println("Space String :"+ spacing_entities); byte[] byteArray = // spacing_entities.getBytes( Charset.forName("UTF-8") ); // Charset.forName("UTF-8").encode( s2 ).array(); {-30, -128, -125, 44, -30, -128, -126, 44, 32, 44, -62, -96}; System.out.println("Bytes:"+ Arrays.toString( byteArray ) ); try { System.out.format("Bytes to String[%S] \n ", new String(byteArray, "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); }
- ➩ ASCII транслитерации Строка Unicode для Java.
unidecode
String initials = Unidecode.decode( s2 );
- ➩ с помощью
Guava
: Google CoreLibraries for Java
.Для URL-кодирования для пробела используйте Guava laibrary.String replaceFrom = CharMatcher.WHITESPACE.replaceFrom( s2, " " );
String encodedString = UrlEscapers.urlFragmentEscaper().escape(inputString);
- ➩ Для преодоления этой проблемы используется
String.replaceAll()
с некоторымиRegularExpression
.// \p{Z} or \p{Separator}: any kind of whitespace or invisible separator. s2 = s2.replaceAll("\\p{Zs}", " "); s2 = s2.replaceAll("[^\\p{ASCII}]", " "); s2 = s2.replaceAll(" ", " ");
- ➩ Используя java.text.Normalizer.Form . Это перечисление предоставляет константы четырех форматов нормализации Unicode, которые описаны в стандартном приложении Unicode № 15 - формах нормализации Unicode и два метода доступа к ним.
s2 = Normalizer.normalize(s2, Normalizer.Form.NFKC);
Тестирование Строки и выходы на разных подходах, таких как ➩ Unidecode, Normalizer, StringUtils .
String strUni = "Tĥïŝ ĩš â fůňķŷ Šťŕĭńġ Æ,Ø,Ð,ß"; // This is a funky String AE,O,D,ss String initials = Unidecode.decode( strUni ); // Following Produce this o/p: Tĥïŝ ĩš â fůňķŷ Šťŕĭńġ Æ,Ø,Ð,ß String temp = Normalizer.normalize(strUni, Normalizer.Form.NFD); Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+"); temp = pattern.matcher(temp).replaceAll(""); String input = org.apache.commons.lang3.StringUtils.stripAccents( strUni );
Использование Unidecode - это
best choice
, Мой последний код, показанный ниже.public static void main(String[] args) { String s1 = "My Sample Space Data", s2 = "My Sample Space Data"; String initials = Unidecode.decode( s2 ); if( s1.equals(s2)) { //[ , ] %A0 - %2C - %20 « http://www.ascii-code.com/ System.out.println("Equal Unicode Strings"); } else if( s1.equals( initials ) ) { System.out.println("Equal Non Unicode Strings"); } else { System.out.println("Not Equal"); } }