Лучше ли сравнивать строки с помощью toLowerCase или toUpperCase в JavaScript?

Я прохожу обзор кода, и мне любопытно, лучше ли конвертировать строки в верхний или нижний регистр в JavaScript при попытке сравнить их, игнорируя регистр.

банальный пример:

var firstString = "I might be A different CASE";
var secondString = "i might be a different case";
var areStringsEqual = firstString.toLowerCase() === secondString.toLowerCase();

или я должен сделать это:

var firstString = "I might be A different CASE";
var secondString = "i might be a different case";
var areStringsEqual = firstString.toUpperCase() === secondString.toUpperCase();

похоже, что либо "должен", либо будет работать с ограниченными наборами символов, такими как только английские буквы, поэтому он один более надежный, чем другой?

в качестве примечания MSDN рекомендует нормализовать строки для верхний регистр, но это для управляемого кода (предположительно C# & F#, но у них есть причудливые StringComparers и базовые библиотеки):http://msdn.microsoft.com/en-us/library/bb386042.aspx

2 ответов


пересмотренный ответ

прошло довольно много времени, когда я ответил на этот вопрос. В то время как культурные проблемы все еще остаются верными (и я не думаю, что они когда-либо уйдут), развитие ECMA-402 standard сделал мой оригинальный ответ... устаревший (или устаревший?).

лучшее решение для сравнения локализованных строк, похоже, использует функцию toLocaleCompare () с соответствующими локалями и опциями:

var locale = 'en'; // that should be somehow detected and passed on to JS
var firstString = "I might be A different CASE";
var secondString = "i might be a different case";
if (firstString.localeCompare(secondString, locale, {sensitivity: 'accent'}) === 0) {
    // do something when equal
}

это сравнить две строки-нечувствительные к регистру, но чувствительные к акценту (например,= ля.)
Если этого недостаточно по соображениям производительности, вы можете использовать либо toLocaleUpperCase() или toLocaleLowerCase() передача локали в качестве параметра:

if (firstString.toLocaleUpperCase(locale) === secondString.toLocaleUpperCase(locale)) {
    // do something when equal
}

в теории не должно быть никаких различий. На практике тонкие детали реализации (или отсутствие реализации в данном браузере) могут давать разные результаты...

оригинальный ответ

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

здесь тонны проблем с преобразованием case, что неизбежно приводит к функциональным проблемам, если вы хотите преобразовать регистр символов без указания языка (например, в случае JavaScript). Например:

  1. есть много естественных языков, которые не имеют понятие верхний и Нижний регистры. Нет смысла пытаться преобразовать их (хотя это будет работать).
  2. существуют языковые правила преобразования строки. Немецкий sharp S символ (ß) обязательно преобразуется в две буквы верхнего регистра S (SS).
  3. турецкий и азербайджанский (или азербайджанский, если хотите) имеет "очень странный" концепция двух символов i: dotless I (который преобразуется в верхний регистр I) и dotted i (который преобразуется в верхний регистр I
  4. греческий язык имеет много "странных" правил преобразования. Одно конкретное правило касается заглавной буквы Сигма (Σ), который в зависимости от места в слове имеет два строчных двойника: регулярную Сигму (σ) и конечную Сигму (ς). Существуют также другие правила преобразования в отношении "акцентированных" символов, но они обычно опущены во время реализации преобразования функция.
  5. в некоторых языках название-заглавные буквы, т. е. lj который должен быть преобразован в такие вещи, как LJ или менее подходяще LJ. То же самое можно сказать и о лигатур.
  6. наконец, есть много совместимость символов это может означать то же самое, что и то, с чем вы пытаетесь сравнить, но состоять из совершенно разных символов. Что еще хуже, такие вещи, как" ae", могут быть эквивалентом" ä " на немецком и финском языках, но эквивалент " æ " на датском языке.

Я пытаюсь убедить вас, что действительно лучше сравнивать пользовательский ввод буквально, а не преобразовывать его. Если это не связано с пользователем, это, вероятно, не имеет значения, но преобразование случая всегда займет время. Зачем?


это никогда не зависит от браузера, поскольку это только javascript, который участвует. как даст производительности на основе никаких знаков должны быть изменены(листать дело)

var areStringsEqual = firstString.toLowerCase() === secondString.toLowerCase();
var areStringsEqual = firstString.toUpperCase() === secondString.toUpperCase();

Если вы используете тест, подготовленный @adeneo вы можете чувствовать, что это зависит от браузера, но и сделать некоторые другие тестовые входы, как "АААААААААААААААААААААААААААА" & "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" и сравнить.

производительность Javascript зависит от браузера, если какой-либо DOM api или любой dom манипуляция / взаимодействие есть, иначе для всего простого javascript это даст одинаковую производительность.