Симон Моурир дал этот пример :
object o = null;
DateTime d = (DateTime)o; // NullReferenceException
, где unboxing преобразование (литье) из object
(или из одного из классов System.ValueType
или System.Enum
или из типа интерфейса) - тип значения (кроме Nullable<>
) сам по себе дает NullReferenceException
.
В другом направлении конверсия бокса из a Nullable<>
, которая имеет HasValue
, равную false
, на ссылочный тип, может дать ссылку null
, которая затем может привести к NullReferenceException
. Классический пример:
DateTime? d = null;
var s = d.ToString(); // OK, no exception (no boxing), returns ""
var t = d.GetType(); // Bang! d is boxed, NullReferenceException
Иногда бокс происходит по-другому. Например, с помощью этого не общего метода расширения:
public static void MyExtension(this object x)
{
x.ToString();
}
следующий код будет проблематичным:
DateTime? d = null;
d.MyExtension(); // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here.
Эти случаи возникают из-за специальных правил, используемых во время выполнения при боксе Nullable<>
экземпляров.
это должно помочь: его названное акцентное сгибание:
http://alistapart.com/article/accent-folding-for-auto-complete
Нет более простого способа «деактивировать», о котором я могу думать, но ваша замена может быть упрощена:
var makeComp = (function(){
var accents = {
a: 'àáâãäåæ',
c: 'ç',
e: 'èéêëæ',
i: 'ìíîï',
n: 'ñ',
o: 'òóôõöø',
s: 'ß',
u: 'ùúûü',
y: 'ÿ'
},
chars = /[aceinosuy]/g;
return function makeComp(input) {
return input.replace(chars, function(c){
return '[' + c + accents[c] + ']';
});
};
}());
Я сделал версию Prototype этого:
String.prototype.strip = function() {
var translate_re = /[öäüÖÄÜß ]/g;
var translate = {
"ä":"a", "ö":"o", "ü":"u",
"Ä":"A", "Ö":"O", "Ü":"U",
" ":"_", "ß":"ss" // probably more to come
};
return (this.replace(translate_re, function(match){
return translate[match];})
);
};
Используйте как:
var teststring = 'ä ö ü Ä Ö Ü ß';
teststring.strip();
Это изменит строку на a_o_u_A_O_U_ss
Пришел на эту старую нить и подумал, что я попробую свою руку при выполнении быстрой функции. Я полагаюсь на упорядочение переменных параметра ORs, разделенных каналами, когда они совпадают в функции replace (), вызывает вызов. Моя цель состояла в том, чтобы использовать стандартную функцию regex-реализации. Функция javascript replace () использует как можно больше, так что тяжелая обработка может происходить в низкоуровневом обозреваемом браузером пространстве, а не в дорогих сопоставлениях javascript char-by-char .
Это совсем не научный, но мой старый Android-телефон Huawei IDEOS вялый, когда я подключаю другие функции в этом потоке к моему автозаполнению, а эта функция застегивается вдоль:
function accentFold(inStr) {
return inStr.replace(
/([àáâãäå])|([ç])|([èéêë])|([ìíîï])|([ñ])|([òóôõöø])|([ß])|([ùúûü])|([ÿ])|([æ])/g,
function (str, a, c, e, i, n, o, s, u, y, ae) {
if (a) return 'a';
if (c) return 'c';
if (e) return 'e';
if (i) return 'i';
if (n) return 'n';
if (o) return 'o';
if (s) return 's';
if (u) return 'u';
if (y) return 'y';
if (ae) return 'ae';
}
);
}
Если вы jQuery dev, вот удобный пример использования этой функции; вы можете использовать: icontains так же, как вы бы использовали: содержит в селекторе:
jQuery.expr[':'].icontains = function (obj, index, meta, stack) {
return accentFold(
(obj.textContent || obj.innerText || jQuery(obj).text() || '').toLowerCase()
)
.indexOf(accentFold(meta[3].toLowerCase())
) >= 0;
};
Я искал что-то подобное, но вместо создания регулярного выражения я просто хотел заменить акцентированные символы на их эквиваленты ASCII. Вдохновленный ответом 999 и статьей в A List Apart ( http://www.alistapart.com/articles/accent-folding-for-auto-complete/ ), я пришел op со следующей функцией. Конечно, он может быть изменен для конкретных реализаций:
var accent_fold = (function () {
var accent_map = {
'à': 'a', 'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', // a
'ç': 'c', // c
'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', // e
'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', // i
'ñ': 'n', // n
'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ø': 'o', // o
'ß': 's', // s
'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u', // u
'ÿ': 'y' // y
};
return function accent_fold(s) {
if (!s) { return ''; }
var ret = '';
for (var i = 0; i < s.length; i++) {
ret += accent_map[s.charAt(i)] || s.charAt(i);
}
return ret;
};
} ());
использование:
var someText = "lôõk mä, nø hånds!";
someText = accent_fold(someText);
// someText now contains: "look ma, no hands!"
Во-первых, я бы рекомендовал оператор switch вместо длинной строки if-else, если ...
Тогда я не уверен, почему вам не нравится ваше текущее решение. Это, безусловно, самый чистый. Что вы подразумеваете, не принимая во внимание «все символы»?
В JavaScript нет стандартного метода для сопоставления букв с буквой ASCII за пределами использования сторонней библиотеки, поэтому тот, который вы написали, как и любой другой.
Кроме того, «ß» я считаю, что карты относятся к «ss», а не к одному «s». И остерегайтесь «i» с и без точки на турецком языке - я считаю, что они относятся к разным буквам.
Существует способ, чтобы "" deaccent "сравниваемая строка" без использования функции замещения, в которой перечислены все акценты, которые вы хотите удалить ...
самое простое решение Я могу думать об удалении акцентов (и других диакритических знаков) из строки.
См. в действии:
var string = "Ça été Mičić. ÀÉÏÓÛ";
console.log(string);
var string_norm = string.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
console.log(string_norm);
Надеюсь, что это поможет.
Вы также можете использовать http://fusejs.io для нечеткого поиска.