Содержит регистронезависимый

414

У меня есть следующее:

if (referrer.indexOf("Ral") == -1) { ... }

То , что я хотел бы сделать , это Ralчувствительно к регистру, так что это может быть RAl, rAlи т.д. , и по- прежнему совпадают.

Есть ли способ сказать, что Ralон должен быть без учета регистра?

Нейт Пэт
источник
3
Я думаю, что регулярное выражение без учета регистра является более элегантным решением, но все должны помнить о подводных камнях создания RegExpнепосредственного пользовательского ввода. Например, пользователь может войти, *и в конструктор будет выдана ошибка RegExp. Принятое решение не имеет этой проблемы.
Фле

Ответы:

605

Добавить .toLowerCase()после referrer. Этот метод превращает строку в строчную строку. Затем .indexOf()используйте ralвместо Ral.

if (referrer.toLowerCase().indexOf("ral") === -1) { 

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

if (!/Ral/i.test(referrer)) {
   //    ^i = Ignore case flag for RegExp
Роб W
источник
16
Последний метод является более правильным; бывшие потерпит неудачу для турецкого I и любого другого подобного проблематичным прописного / строчного пара: i18nguy.com/unicode/turkish-i18n.html
Доменик
23
Для турецкого было бы лучше использовать toLocaleLowerCase()( ref )
Mottie
2
последний не отвечает на вопрос, он только говорит, что если он есть, а не получить индекс совпадения. Либо неправильный заголовок вопроса, либо вопрос.
Маслоу
10
@Maslow Пример вопроса касался тестирования нечувствительности к регистру. Если вы хотите получить индекс, используйте метод String.search :var index = referrer.search(/Ral/i);
Роб W
7
Дополнительное усложнение подхода динамического регулярного выражения состоит в том, что если строка поиска, например «Ral», содержит специальные символы регулярного выражения, такие как $. *? и т.д., у вас будут проблемы, поэтому вам нужно будет избегать специальных символов, см. ответ Майка Самуэля на этот пост: заканчивается с помощью JavaScript
zachelrath
94

Другой вариант - использовать метод поиска следующим образом:

if (referrer.search(new RegExp("Ral", "i")) == -1) { ...

Это выглядит более элегантно, чем преобразование всей строки в нижний регистр, и это может быть более эффективным.
В toLowerCase()коде есть два прохода над строкой, один проход на всю строку, чтобы преобразовать ее в нижний регистр, а другой - поиск нужного индекса.
С RegExpкодом есть один проход по строке, которая выглядит так, чтобы соответствовать желаемому индексу.

Поэтому на длинных строках я рекомендую использовать RegExpверсию (я думаю, что на коротких строках эта эффективность достигается за счет создания RegExpобъекта)

Кфир Эрез
источник
2
Это также немного быстрее, основываясь на моих тестах: jsperf.com/case-insensitive-indexof
Илан Бяла
6
На 2018.10.24 toLowerCase выигрывает с большим отрывом в Chrome. toLowerCase (95 914 378 - ± 0,89% - самый быстрый), регулярное выражение indexOf (269 307 - ± 0,87% на 100% медленнее)
nixkuroi
21

Используйте RegExp:

if (!/ral/i.test(referrer)) {
    ...
}

Или используйте .toLowerCase():

if (referrer.toLowerCase().indexOf("ral") == -1)
gilly3
источник
1
+1, это потенциально может быть более правильным, избегая «турецкой проблемы я» и другие подобные подводные камни: i18nguy.com/unicode/turkish-i18n.html
Доменик
15

Начиная с ES2016, вы также можете использовать метод немного лучше / проще / элегантнее (с учетом регистра):

if (referrer.includes("Ral")) { ... }

или (без учета регистра):

if (referrer.toLowerCase().includes(someString.toLowerCase())) { ... }

Вот некоторые сравнения .indexOf()и .includes(): https://dev.to/adroitcoder/includes-vs-indexof-in-javascript

Лукаш Матушевский
источник
1
Я не думаю, что включает в себя без учета регистра
Кайл с
4
@Kyles includesявляется чувствительны к регистру в Chrome: попробуйте 'fooBar'.includes('bar')==>false
drzaus
10

Здесь есть пара подходов.

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

if (referrer.toLowerCase().indexOf("Ral".toLowerCase()) == -1) {
    ...

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

String.prototype.indexOfInsensitive = function (s, b) {
    return this.toLowerCase().indexOf(s.toLowerCase(), b);
}

// Then invoke it
if (referrer.indexOfInsensitive("Ral") == -1) { ...
cheeken
источник
1
Для современных браузеров, которые поддерживают defineProperty, я предлагаю Object.defineProperty(String.prototype, 'indexOfInsensitive', {value: function(s,b){return this.toLowerCase().indexOf((s+'').toLowerCase(),b);}});. Два обновления: явное преобразование строк с использованием (s+'')и не перечислимый в цикле ( for(var i in '') ... не отображается indexOfInsensitive.
Роб W
5
if (referrer.toUpperCase().indexOf("RAL") == -1) { ...
Кендалл Фрей
источник
@ Domenic: При всем уважении к турецкой культуре, Турции следует подумать о реформе правописания, чтобы упростить этот аспект. В Китае был проведен ряд реформ по упрощению , а в Турции проживает менее 10% населения Китая, а алфавит намного проще. Это может быть сделано.
Дан Даскалеску
5

Вы можете попробовать это

str = "Wow its so COOL"
searchStr = "CoOl"

console.log(str.toLowerCase().includes(searchStr.toLowerCase()))

Бакарали Сунасра
источник
3

Пример для любого языка:

'My name is Хведор'.toLocaleLowerCase().includes('ХвЕдОр'.toLocaleLowerCase())
alex_1948511
источник
2

Это 2016 год, и нет четкого способа, как это сделать? Я надеялся на некоторый copypasta. Я пойду.

Замечания по дизайну: я хотел минимизировать использование памяти и, следовательно, улучшить скорость - чтобы не было копирования / изменения строк. Я предполагаю, что V8 (и другие двигатели) могут оптимизировать эту функцию.

//TODO: Performance testing
String.prototype.naturalIndexOf = function(needle) {
    //TODO: guard conditions here

    var haystack = this; //You can replace `haystack` for `this` below but I wan't to make the algorithm more readable for the answer
    var needleIndex = 0;
    var foundAt = 0;
    for (var haystackIndex = 0; haystackIndex < haystack.length; haystackIndex++) {
        var needleCode = needle.charCodeAt(needleIndex);
        if (needleCode >= 65 && needleCode <= 90) needleCode += 32; //ToLower. I could have made this a function, but hopefully inline is faster and terser
        var haystackCode = haystack.charCodeAt(haystackIndex);
        if (haystackCode >= 65 && haystackCode <= 90) haystackCode += 32; //ToLower. I could have made this a function, but hopefully inline is faster and terser

        //TODO: code to detect unicode characters and fallback to toLowerCase - when > 128?
        //if (needleCode > 128 || haystackCode > 128) return haystack.toLocaleLowerCase().indexOf(needle.toLocaleLowerCase();
        if (haystackCode !== needleCode)
        {
            foundAt = haystackIndex;
            needleIndex = 0; //Start again
        }
        else
            needleIndex++;

        if (needleIndex == needle.length)
            return foundAt;
    }

    return -1;
}

Моя причина для имени:

  • Должен иметь IndexOf в имени
  • Не добавлять суффикс - Of относится к следующему параметру
  • Не используйте caseInsensitive, который оооочень долго
  • «Natural» - хороший кандидат, потому что сравнение с учетом регистра по умолчанию не является естественным для людей.

Почему бы нет...:

  • toLowerCase() - потенциальные повторные вызовы toLowerCase по той же строке.
  • RegExpНеловко искать с переменной. Даже объект RegExp неудобно экранировать символы
Тодд
источник
2
Это 2016 год, и вы все еще думаете, что английский (или другие языки только для ASCII) является единственным языком в мире?
Роланд Иллиг
3
@RolandIllig Ой. Мой ответ не учитывает другие культуры, это недостаток. Я приветствовал бы любое понимание расширения поддержки большего количества культур, мир - лучшее место с сотрудниками.
Тодд
1

Для лучшего поиска используйте следующий код,

var myFav   = "javascript";
var theList = "VB.NET, C#, PHP, Python, JavaScript, and Ruby";

// Check for matches with the plain vanilla indexOf() method:
alert( theList.indexOf( myFav ) );

// Now check for matches in lower-cased strings:
alert( theList.toLowerCase().indexOf( myFav.toLowerCase() ) );

В первом alert () JavaScript возвращал «-1» - другими словами, indexOf () не нашел соответствия: это просто потому, что «JavaScript» находится в нижнем регистре в первой строке и правильно прописывается во второй. Для выполнения поиска без учета регистра с помощью indexOf () вы можете сделать обе строки прописными или строчными. Это означает, что, как и во втором alert (), JavaScript будет проверять только наличие строки, которую вы ищете, заглавные буквы игнорируются.

Ссылка, http://freewebdesigntutorials.com/javaScriptTutorials/jsStringObject/indexOfMethod.htm

Диганта Кумар
источник
1

Если referrerэто массив, вы можете использоватьfindIndex()

 if(referrer.findIndex(item => 'ral' === item.toLowerCase()) == -1) {...}
A-Sharabiani
источник
0

Вот мой дубль:

Сценарий :

var originalText = $("#textContainer").html()
$("#search").on('keyup', function () {
  $("#textContainer").html(originalText)
  var text = $("#textContainer").html()
  var val = $("#search").val()
  if(val=="") return;
  var matches = text.split(val)
  for(var i=0;i<matches.length-1;i++) {
    var ind =  matches[i].indexOf(val)
    var len = val.length
      matches[i] = matches[i] + "<span class='selected'>" + val + "</span>"
  }
  $("#textContainer").html(matches.join(""))

HTML:

<input type="text" id="search">
<div id="textContainer">
lorem ipsum is simply dummy text of the printing and typesetting industry. lorem ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of letraset sheets containing lorem ipsum passages, and more recently with desktop publishing software like Aldus pagemaker including versions of lorem ipsum.</div>

Codepen

Майкл Селтенрайх
источник