2012-01-24 17 views
279

Mam następujący:JavaScript zawiera przypadek niewrażliwe

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

Co chciałbym zrobić, to zrobić Ral wielkość liter ma znaczenie, tak że może być RAl, rAl, itd. I nadal pasuje.

Czy istnieje sposób na stwierdzenie, że Ral musi być niewrażliwy na wielkość znaków?

+3

Myślę, że regex niewrażliwy na wielkość liter jest bardziej eleganckim rozwiązaniem, ale każdy powinien pamiętać o pułapkach tworzenia 'RegExp' bezpośrednio z danych wprowadzanych przez użytkownika. Na przykład użytkownik może wpisać '*', a błąd zostanie zgłoszony w konstruktorze "RegExp'. Przyjęte rozwiązanie nie ma tego problemu. – pllee

+1

Możliwy duplikat [indexOf Case Sensitive?] (Http://stackoverflow.com/questions/1126227/indexof-case-sensitive) – HadiRj

Odpowiedz

416

Dodaj .toLowerCase() po referrer. Ta metoda zamienia łańcuch w łańcuch małych liter. Następnie użyj .indexOf(), używając ral zamiast Ral.

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

To samo można osiągnąć za pomocą wyrażenia regularnego (szczególnie przydatne, gdy chcesz przetestować przed dynamicznych wzorów):

if (!/Ral/i.test(referrer)) { 
    // ^i = Ignore case flag for RegExp 
+13

Ta ostatnia metoda jest bardziej poprawna; pierwsza nie powiedzie się dla tureckiego I i innych takich problematycznych wielkich/małych liter: http://www.i18nguy.com/unicode/turkish-i18n.html – Domenic

+15

Dla Turcji lepiej byłoby użyć 'toLocaleLowerCase()' ([ref] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase)) – Mottie

+2

ten ostatni nie odpowiada na pytanie, mówi tylko, czy jest tam, nie uzyskać indeksu meczu. Tytuł pytania jest błędny lub pytanie. – Maslow

4
if (referrer.toUpperCase().indexOf("RAL") == -1) { ... 
+1

-1, będzie miał problemy z http: // www.i18nguy.com/unicode/turkish-i18n.html – Domenic

+3

@Domenic +1 do tej odpowiedzi, nie będzie mieć problemów z metaznakami regex z dynamicznego wprowadzania danych, co jest znacznie bardziej prawdopodobnym problemem. -1 do wszystkich pozostałych odpowiedzi. –

+0

toLowerCase() jest bardziej niezawodnym rozwiązaniem, ponieważ mogą występować problemy z nierównoleganiem symboli ASC2 dużymi literami. –

18

Użyj RegExp:

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

Lub użyj .toLowerCase():

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

+1, to może być bardziej poprawne, unikając "problemu tureckiego I" i innych takich pułapek: http://www.i18nguy.com/unicode/turkish-i18n.html – Domenic

+0

jeśli "ral" jest dynamiczny, to również musi być przekonwertowany na małe litery. – Kurkula

9

Istnieje kilka podejść tutaj.

Jeśli chcesz wykonać sprawdzanie niewrażliwe na wielkość liter tylko dla tego wystąpienia, wykonaj następujące czynności.

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

Alternatywnie, jeśli regularnie wykonywania tej kontroli, można dodać nową metodę indexOf() -Jak do String, ale sprawiają, że wielkość liter ma znaczenie.

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

// Then invoke it 
if (referrer.indexOfInsensitive("Ral") == -1) { ... 
+0

Jeśli rozszerzysz prototyp o konkretną implementację 'indexOf', nie zapomnij o opcjonalnym drugim parametrze: Pozycja początkowa (' a a.indexOf ('a', 1) === 2'). –

+0

@RobW Dobre połączenie; zmienione. – cheeken

+1

Dla nowoczesnych przeglądarek obsługujących ['defineProperty'] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty), proponuję' Object.defineProperty (String.prototype, 'indexOfInsensitive', {value: function (s, b) {return this.toLowerCase(). indexOf ((s + ''). doLowerCase(), b);}}); '. Dwie aktualizacje: jawna konwersja ciągów za pomocą '(s + '')' i nieprzeliczalna w pętli ('for (var i in '') ...' nie wyświetla 'indexOfInsensitive' . –

1

zrobić lepiej szukaj użyć 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 alert(), JavaScript zwrócony "-1" - innymi słowy, indexOf() nie znaleźliśmy mecz : dzieje się tak dlatego, że "JavaScript" jest pisany małymi literami w pierwszym łańcuchu znaków i odpowiednio pisany wielkimi literami w drugim. Aby wykonać wyszukiwanie bez rozróżniania wielkości liter za pomocą metody indexOf(), możesz ustawić oba łańcuchy jako wielkie lub małe litery. Oznacza to, że podobnie jak w drugim alertu(), JavaScript sprawdza jedynie występowanie szukanego ciągu znaków, ignorując wielkie litery.

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

67

Kolejne opcji jest użycie metody wyszukiwania następująco:

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

To wygląda bardziej elegancki następnie przekształcając cały ciąg na małe i mogą być bardziej efektywne.
Z toLowerCase() kod ma dwa przejścia przez ciąg, jedno przejście jest na całym łańcuchu, aby przekonwertować go na małe litery, a drugie na szukanie pożądanego indeksu.
Z RegExp kod ma jedno przejście przez ciąg, który wygląda, aby dopasować żądany indeks.

Dlatego na długich ciągów polecam użyć wersji RegExp (myślę, że na krótkich ciągów sprawność ta przychodzi na rachunku tworzenia obiektu RegExp chociaż)

+7

+1, to rozwiązanie pozwala dla wyrażenia, które ma być przechowywane w zmiennej –

+1

Jest to bliższe odpowiedzi, ponieważ z testem lub dopasowaniem nie można uzyskać indeksu. – FlavorScape

+1

Jest to również nieco szybciej w oparciu o moje testy: http://jsperf.com/niewrażliwy na wielkość liter-indexof –

1

To 2016, i nie ma wyraźny sposób jak to zrobić? Miałem nadzieję na jakąś copypastę. Muszę iść.

Uwagi do projektu: chciałem zminimalizować wykorzystanie pamięci, a zatem poprawić prędkość - 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:

  • IndexOf powinien mieć w nazwie
  • Nie dodanie przyrostka - Z odnosi się do następnego parametru
  • nie wolno używać „CASEINSENSITIVE "To jest bardzo długie"
  • "naturalny" jest dobrym kandydatem, ponieważ domyślne porównania wielkości liter nie są dla ludzi naturalne.

Dlaczego nie ...:

  • toLowerCase() - potencjalne ponawianych wezwań toLowerCase na tym samym ciąg.
  • RegExp - niezręczny do wyszukiwania ze zmienną. Nawet obiekt RegExp jest niewygodne konieczności ucieczki znaki
+0

Oddychanie świeżym powietrzem Ktoś właściwie poświęca czas na przemyślenie i wyjaśnienie argumentów związanych z ich nazwą funkcji. lepsze miejsce właśnie tam. –

0

Oto moje zdanie:

Script:

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

Powiązane problemy