2008-10-07 16 views
235

Próbuję uzyskać wyszukiwanie bez rozróżniania wielkości liter z dwoma ciągami w działaniu JavaScript.JavaScript: niewrażliwe na wielkość liter

Normalnie byłoby tak:

var string="Stackoverflow is the BEST"; 
var result= string.search(/best/i); 
alert(result); 

/i flaga byłaby dla wielkości liter.

Ale muszę wyszukać drugi ciąg; bez flagi to działa idealnie:

var string="Stackoverflow is the BEST"; 
var searchstring="best"; 
var result= string.search(searchstring); 
alert(result); 

Jeśli dodać flagę /i do powyższego przykładu byłoby szukać searchstring a nie za to, co jest w zmiennej „searchstring” (następny przykład nie działa):

var string="Stackoverflow is the BEST"; 
var searchstring="best"; 
var result= string.search(/searchstring/i); 
alert(result); 

Jak mogę to osiągnąć?

Odpowiedz

317

Tak, użyj .match, zamiast .search. Wynik wywołania .match zwróci rzeczywisty ciąg, który został dopasowany, ale nadal może być używany jako wartość logiczna.

var string = "Stackoverflow is the BEST"; 
var result = string.match(/best/i); 
// result == 'BEST'; 

if (result){ 
    alert('Matched'); 
} 

Użycie wyrażenia regularnego jak to jest prawdopodobnie tidiest i najbardziej oczywistym sposobem, aby to zrobić w JavaScript, ale należy pamiętać, że jest wyrażenie regularne, a zatem może zawierać metaznaki regex. Jeśli chcesz wziąć sznurek z zewnątrz (na przykład dane wprowadzone przez użytkownika), lub jeśli chcesz uniknąć konieczności ucieczki dużo metaznaków, to jesteś prawdopodobnie najlepiej używając indexOf tak:

matchString = 'best'; 
// If the match string is coming from user input you could do 
// matchString = userInput.toLowerCase() here. 

if (string.toLowerCase().indexOf(matchString) != -1){ 
    alert('Matched'); 
} 
+11

Co jeśli MatchString ma wartość „najlepszy”? Właściwe wyszukiwanie niewrażliwe na wielkość liter powinno znaleźć to wydarzenie. W twoim przypadku prawdopodobnie będziesz musiał również wywołać metodę LowerCase() w wyszukiwaniu. –

+0

Dodałem komentarz, aby odzwierciedlić ten fakt, dzięki. – Dan

+7

Przepraszam, jak możesz przekonwertować "najlepszy" na zmienną w pierwszym przykładzie? '' 'string.match (/ best/i);' '' –

138

Wymień

var result= string.search(/searchstring/i); 

z

var result= string.search(new RegExp(searchstring, "i")); 
+5

To dość niechlujny sposób, aby zabezpieczyć się przed nieoczekiwanymi metaznakami wyrażeń regularnych. – Dan

+30

Dan, wątpię, czy moja odpowiedź zasługuje na -1 od ciebie. Próbowałem pomóc ChrisBo, poprawiając jego niewłaściwe użycie JavaScript, a mianowicie: var result = string.search (/ searchstring/i); do właściwego, w którym zastosowano zmienny łańcuch wyszukiwania w sposób zamierzony. –

+7

Dan ma rację (choć prawdopodobnie chciał powiedzieć "* nie * mierzy"): 's = 'a [b'; r = new RegExp (s) 'powoduje błąd składniowy (niezakończona klasa znaków) –

33

Jeśli jesteś po prostu szukają sznurku zamiast bardziej skomplikowanego wyrażenia regularnego, można wykorzystać indexOf() - ale Pamiętam na małe oba ciągi pierwsze dlatego indexOf() jest wielkość liter:

var string="Stackoverflow is the BEST"; 
var searchstring="best"; 

// lowercase both strings 
var lcString=string.toLowerCase(); 
var lcSearchString=searchstring.toLowerCase(); 

var result = lcString.indexOf(lcSearchString)>=0; 
alert(result); 

Albo w jednej linii:

var result = string.toLowerCase().indexOf(searchstring.toLowerCase())>=0; 
2

Jeśli chodzi o „niezakończony klasy charakter” sprawy, usuwając wszystkie niealfanumeryczne znaków byłoby pomocne:

searchstring = searchstring.replace(/[^a-zA-Z 0-9]+/g,'');
-1

zauważyłem, że jeśli użytkownik wprowadzi ciąg tekstu, ale pozostawia wejście bez wybrania którejkolwiek z opcji autouzupełniania żadnej wartości jest ustawione na ukrytym wejściu, nawet jeśli ciąg pokrywa się z jednym w tablicy. Tak, z pomocą innych odpowiedzi Zrobiłem to:

var $local_source = [{ 
     value: 1, 
     label: "c++" 
    }, { 
     value: 2, 
     label: "java" 
    }, { 
     value: 3, 
     label: "php" 
    }, { 
     value: 4, 
     label: "coldfusion" 
    }, { 
     value: 5, 
     label: "javascript" 
    }, { 
     value: 6, 
     label: "asp" 
    }, { 
     value: 7, 
     label: "ruby" 
    }]; 
    $('#search-fld').autocomplete({ 
     source: $local_source, 
     select: function (event, ui) { 
      $("#search-fld").val(ui.item.label); // display the selected text 
      $("#search-fldID").val(ui.item.value); // save selected id to hidden input 
      return false; 
     }, 
     change: function(event, ui) { 

      var isInArray = false; 

      $local_source.forEach(function(element, index){ 

       if ($("#search-fld").val().toUpperCase() == element.label.toUpperCase()) { 
        isInArray = true; 
        $("#search-fld").val(element.label); // display the selected text 
        $("#search-fldID").val(element.value); // save selected id to hidden input 
        console.log('inarray: '+isInArray+' label: '+element.label+' value: '+element.value); 
       }; 

      }); 

      if(!isInArray){ 

       $("#search-fld").val(''); // display the selected text 
       $("#search-fldID").val(ui.item? ui.item.value : 0); 

      } 
     } 
1

Istnieją dwa sposoby przypadku niewrażliwych porównania:

  1. konwersji ciągów znaków na wielkie litery, a następnie porównać je za pomocą ścisłego operatora (===). Jak operator ścisłej traktuje argumenty czytać rzeczy pod adresem: http://www.thesstech.com/javascript/relational-logical-operators

  2. Pattern Matching stosując metody wyrażenie:

    Użyj pola „Znajdź” metody strun przez przypadek niewrażliwego wyszukiwania. Przeczytaj o poszukiwaniu i innych metod łańcuch na: http://www.thesstech.com/pattern-matching-using-string-methods

    <!doctype html> 
        <html> 
        <head> 
         <script> 
    
         // 1st way 
    
         var a = "apple"; 
         var b = "APPLE"; 
         if (a.toUpperCase() === b.toUpperCase()) { 
          alert("equal"); 
         } 
    
         //2nd way 
    
         var a = " Null and void"; 
         document.write(a.search(/null/i)); 
    
         </script> 
        </head> 
    </html> 
    
14

Załóżmy, że chcemy znaleźć ciąg zmienny needle w ciągu zmiennej haystack. Istnieją trzy pułapek:

  1. Internationalized aplikacje powinny unikać string.toUpperCase i string.toLowerCase. Użyj wyrażenia regularnego, które zamiast tego ignoruje wielkość liter. Na przykład: var needleRegExp = new RegExp(needle, "i");, a następnie needleRegExp.test(haystack).
  2. Ogólnie możesz nie znać wartości needle. Należy uważać, aby needle nie zawierało żadnego wyrażenia regularnego special characters. Uciec z nich za pomocą needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");.
  3. W innych przypadkach, jeśli chcesz dokładnie dopasować needle i haystack, po prostu ignorując przypadek, pamiętaj, aby dodać "^" na początku i "$" na końcu swojego konstruktora wyrażeń regularnych.

punkty Robienie (1) i (2) pod uwagę, czego przykładem może być:

var haystack = "A. BAIL. Of. Hay."; 
var needle = "bail."; 
var needleRegExp = new RegExp(needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "i"); 
var result = needleRegExp.test(haystack); 
alert(result); 
+1

Jestem okropny z RegExp, ale czy nie powinno to być "RegExp (needle.replace..'? Then' .test (haystack); '? – Todd

+0

@todd, masz oczywiście rację. Patrz edycje. –

2

Lubię @ odpowiedź CHR15TO, w przeciwieństwie do innych odpowiedzi widziałem na innych podobnych pytań, że odpowiedź faktycznie pokazuje, jak poprawnie uciec przed podanym przez użytkownika ciągiem wyszukiwania (zamiast mówić, że byłoby to konieczne bez pokazywania sposobu).

Jednak nadal jest dość niestabilna i prawdopodobnie relatywnie wolniejsza. Dlaczego więc nie mieć konkretnego rozwiązania tego, co najprawdopodobniej jest wspólnym wymogiem dla programistów? (I dlaczego nie umieścić go w API ES6 BTW?)

Moja odpowiedź [https://stackoverflow.com/a/38290557/887092] na podobnym pytaniem umożliwia następujące:

var haystack = 'A. BAIL. Of. Hay.'; 
var needle = 'bail.'; 
var index = haystack.naturalIndexOf(needle); 
Powiązane problemy