Zawiera bez rozróżniania wielkości liter

413

Mam następujące:

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

Co lubię robić to, aby Ralwielkość liter ma znaczenie, tak że może być RAl, rAlitp i nadal pasuje.

Czy istnieje sposób, aby powiedzieć, że Ralmusi być rozróżniana wielkość liter?

Nate Pet
źródło
3
Myślę, że regex bez uwzględniania wielkości liter jest bardziej eleganckim rozwiązaniem, ale każdy powinien pamiętać o pułapkach związanych z tworzeniem RegExpbezpośrednio na podstawie danych wprowadzonych przez użytkownika. Na przykład użytkownik może wprowadzić, *a konstruktor zgłosi błąd RegExp. Przyjęte rozwiązanie nie ma tego problemu.
pllee

Odpowiedzi:

604

Dodaj .toLowerCase()po referrer. Ta metoda zamienia ciąg znaków na ciąg małych liter. Następnie użyj .indexOf()za pomocą ralzamiast Ral.

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

To samo można również osiągnąć za pomocą wyrażenia regularnego (szczególnie przydatne, gdy chcesz przetestować wzorce dynamiczne):

if (!/Ral/i.test(referrer)) {
   //    ^i = Ignore case flag for RegExp
Rob W.
źródło
16
Ta druga metoda jest bardziej poprawna; pierwszy nie powiedzie się w przypadku tureckiego I i innych takich problematycznych par wielkich i małych liter: i18nguy.com/unicode/turkish-i18n.html
Domenic
23
W przypadku tureckiego lepiej byłoby użyć toLocaleLowerCase()( ref )
Mottie
2
ten drugi nie odpowiada na pytanie, mówi tylko, jeśli tam jest, nie uzyskuje indeksu dopasowania. Albo tytuł pytania jest zły, albo pytanie.
Masłów
10
@Maslow Przykład pytania dotyczył testowania niewrażliwości na wielkość liter. Jeśli chcesz uzyskać indeks, skorzystaj z metody String.search :var index = referrer.search(/Ral/i);
Rob W
7
Dodatkową komplikacją dynamicznego podejścia do wyrażeń regularnych jest to, że jeśli szukany ciąg, np. „Ral”, zawiera znaki specjalne wyrażenia regularnego, takie jak $. *? itd., mielibyście problemy, więc musielibyście uciec od znaków specjalnych, zobacz odpowiedź Mike'a Samuela na ten post: kończy się w JavaScript
zachelrath
94

Inną opcją jest użycie metody wyszukiwania w następujący sposób:

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

Wygląda bardziej elegancko niż konwersja całego łańcucha na małe litery i może być bardziej wydajny.
Gdy toLowerCase()kod ma dwa przejścia nad ciągiem, jedno przejście znajduje się na całym ciągu, aby przekonwertować go na małe litery, a drugie na poszukiwanie pożądanego indeksu.
Z RegExpkodem wystarczy jedno przejście przez ciąg, który wygląda tak, aby pasował do pożądanego indeksu.

Dlatego na długich ciągach polecam używać RegExpwersji (wydaje mi się, że na krótkich ciągach ta wydajność zależy od utworzenia RegExpobiektu)

Kfir Erez
źródło
2
Jest to również trochę szybsze w oparciu o moje testy: jsperf.com/case-insensitive-indexof
Ilan Biala
6
Począwszy od 10.10.2018, toLowerCase wygrywa z dużym marginesem w Chrome. toLowerCase (95 914 378 - ± 0,89% - najszybszy), indeks regexO (269,307 - ± 0,87% 100% wolniej)
nixkuroi
21

Użyj RegExp:

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

Lub użyj .toLowerCase():

if (referrer.toLowerCase().indexOf("ral") == -1)
gilly3
źródło
1
+1, mogłoby to potencjalnie być bardziej poprawne, unikając „problemu tureckiego I” i innych podobnych pułapek: i18nguy.com/unicode/turkish-i18n.html
Domenic
15

Od ES2016 możesz także zastosować nieco lepszą / łatwiejszą / bardziej elegancką metodę (z uwzględnieniem wielkości liter):

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

lub (bez rozróżniania wielkości liter):

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

Oto porównanie .indexOf()i .includes(): https://dev.to/adroitcoder/includes-vs-indexof-in-javascript

Łukasz Matuszewski
źródło
1
Nie sądzę, aby uwzględniono wielkość liter bez uwzględniania wielkości liter
Kyle,
4
@Kyles includesjest wielkość liter w Chrome: Spróbuj 'fooBar'.includes('bar')==>false
drzaus
10

Istnieje tutaj kilka podejść.

Jeśli chcesz wykonać rozróżnianie wielkości liter dla tylko tego wystąpienia, wykonaj następujące czynności:

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

Ewentualnie, jeśli przeprowadzasz tę kontrolę regularnie, możesz dodać do niej nową indexOf()metodę String, ale nie rozróżniaj wielkości liter.

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

// Then invoke it
if (referrer.indexOfInsensitive("Ral") == -1) { ...
policzki
źródło
1
definePropertyProponuję dla nowoczesnych przeglądarek, które obsługują Object.defineProperty(String.prototype, 'indexOfInsensitive', {value: function(s,b){return this.toLowerCase().indexOf((s+'').toLowerCase(),b);}});. Dwie aktualizacje: Jawna konwersja ciągu przy użyciu (s+'')i niepoliczalna w pętli ( for(var i in '') ... nie pokazuje indexOfInsensitive.
Rob W
5
if (referrer.toUpperCase().indexOf("RAL") == -1) { ...
Kendall Frey
źródło
@Domenic: Z całym szacunkiem dla kultury tureckiej Turcja powinna rozważyć reformę pisowni w celu uproszczenia tego aspektu. Chiny przeprowadziły wiele reform upraszczających , a Turcja ma mniej niż 10% populacji Chin i znacznie prostszy alfabet. To może być zrobione.
Dan Dascalescu
5

Możesz tego spróbować

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

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

Bakarali Sunasra
źródło
3

Przykład dla dowolnego języka:

'My name is Хведор'.toLocaleLowerCase().includes('ХвЕдОр'.toLocaleLowerCase())
alex_1948511
źródło
2

Jest rok 2016 i nie ma jasnego sposobu, jak to zrobić? Miałem nadzieję na copypastę. Spróbuję.

Uwagi do projektu: Chciałem zminimalizować zużycie pamięci, a tym samym poprawić szybkość - aby nie było kopiowania / mutowania ciągów. Zakładam, że V8 (i inne silniki) mogą zoptymalizować tę funkcję.

//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;
}

Mój powód dla nazwy:

  • Powinien mieć w nazwie IndexOf
  • Nie dodawaj sufiksu - Of oznacza następujący parametr
  • Nie używaj „caseInsensitive”, który jest zbyt długi
  • „naturalny” jest dobrym kandydatem, ponieważ domyślne porównania z rozróżnianiem wielkości liter nie są naturalne dla ludzi.

Dlaczego nie...:

  • toLowerCase() - potencjalne powtarzające się wywołania toLowerCase na tym samym łańcuchu.
  • RegExp- niewygodne wyszukiwanie ze zmienną. Nawet obiekt RegExp jest niezręczny, gdy trzeba uciec od znaków
Todd
źródło
2
Jest rok 2016 i nadal uważasz, że angielski (lub inne języki tylko ASCII) jest jedynym językiem na świecie?
Roland Illig,
3
@RolandIllig Ouch. Moja odpowiedź nie uwzględnia innych kultur, to wada. Z chęcią przyjrzałbym się szerszemu wsparciu dla większej liczby kultur, świat jest lepszym miejscem dla współpracowników.
Todd
1

Aby przeprowadzić lepsze wyszukiwanie, użyj następującego kodu:

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() ) );

W pierwszym alertie () JavaScript zwrócił „-1” - innymi słowy, indexOf () nie znalazł dopasowania: dzieje się tak po prostu dlatego, że „JavaScript” jest zapisany małymi literami w pierwszym ciągu znaków, a odpowiednio dużymi literami w drugim. Aby wyszukiwać bez rozróżniania wielkości liter za pomocą indexOf (), możesz utworzyć oba ciągi wielkimi lub małymi literami. Oznacza to, że podobnie jak w drugim alertie () JavaScript będzie sprawdzał tylko występowanie szukanego ciągu, wielkie litery są ignorowane.

Odniesienie, http://freewebdesigntutorials.com/javaScriptTutorials/jsStringObject/indexOfMethod.htm

Diganta Kumar
źródło
1

Jeśli referrerjest tablicą, możesz użyćfindIndex()

 if(referrer.findIndex(item => 'ral' === item.toLowerCase()) == -1) {...}
A-Sharabiani
źródło
0

Oto moje zdanie:

Skrypt :

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

Michael Seltenreich
źródło