2012-01-24 9 views
279

Ho il seguente:Javascript contiene case insensitive

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

Quello che mi piace fare è quello di rendere Ral case insensitive, in modo che possa essere RAl, rAl, ecc e ancora corrispondono.

C'è un modo per dire che Ral deve essere maiuscole e minuscole?

+3

Penso che la regex senza distinzione tra maiuscole e minuscole sia la soluzione più elegante ma tutti dovrebbero tenere a mente le insidie ​​della creazione di un 'RegExp' direttamente dall'input dell'utente. Ad esempio, un utente potrebbe immettere '*' e verrà generato un errore nel costruttore 'RegExp'. La soluzione accettata non ha questo problema. – pllee

+1

Possibile duplicato di [indexOf Case Sensitive?] (Http://stackoverflow.com/questions/1126227/indexof-case-sensitive) – HadiRj

risposta

416

Aggiungi .toLowerCase() dopo referrer. Questo metodo trasforma la stringa in una stringa in minuscolo. Quindi, utilizzare .indexOf() utilizzando ral anziché Ral.

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

Lo stesso può essere ottenuta anche utilizzando una Regular Expression (particolarmente utile quando si desidera testare contro modelli dinamici):

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

Quest'ultimo metodo è più corretto; il primo fallirà per il turco I e qualsiasi altra coppia di maiuscole/minuscole così problematiche: http://www.i18nguy.com/unicode/turkish-i18n.html – Domenic

+15

Per il turco, sarebbe meglio usare 'toLocaleLowerCase()' ([ref] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase)) – Mottie

+2

quest'ultimo non risponde alla domanda, dice solo se è lì, non ottenere l'indice della partita. O il titolo della domanda è sbagliato o la domanda. – Maslow

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

-1, avrà problemi con http: // www.i18nguy.com/unicode/turkish-i18n.html – Domenic

+3

@Domenico +1 a questa risposta, non avrà problemi con i metacaratteri delle espressioni regolari dall'input dinamico, che è un problema molto più probabile. -1 a tutte quelle altre risposte. –

+0

toLowerCase() è una soluzione più robusta perché possono esserci problemi con il confronto dei simboli ASC2 in maiuscolo. –

18

Utilizzare un RegExp:

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

In alternativa, utilizzare .toLowerCase():

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

+1, questo potrebbe potenzialmente essere più corretto evitando il "problema Turco I" e altre insidie: http://www.i18nguy.com/unicode/turkish-i18n.html – Domenic

+0

se "ral" è dinamico, allora anche questo deve essere convertito in minuscolo. – Kurkula

9

Ci sono un paio di approcci qui.

Se si desidera eseguire un controllo di case-insensitive proprio per questo esempio, fare qualcosa di simile alla seguente.

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

In alternativa, se si sta eseguendo questo controllo regolarmente, è possibile aggiungere un nuovo metodo indexOf() -come al String, ma lo rendono case insensitive.

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

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

Se estendi il prototipo con un'implementazione specifica di 'indexOf', non dimenticare il secondo parametro opzionale: La posizione di partenza (' 'a a'.indexOf (' a ', 1) === 2'). –

+0

@RobW Buona chiamata; modificato. – cheeken

+1

Per i browser moderni che supportano ['defineProperty'] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty), suggerisco' Object.defineProperty (String.prototype, 'indexOfInsensitive', {value: function (s, b) {return this.toLowerCase(). indexOf ((s + ''). aLowerCase(), b);}}); '. Due aggiornamenti: la conversione stringa esplicita usando '(s + '')', e non enumerabile in un ciclo ('for (var i in '') ...' non mostra 'indexOfInsensitive'. –

1

di fare una ricerca meglio utilizzare il seguente codice,

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

Nel primo alert(), è tornato JavaScript "-1" - in altre parole, indexOf() non ha trovato una corrispondenza : questo è semplicemente perché "JavaScript" è in minuscolo nella prima stringa e correttamente in maiuscolo nel secondo. Per eseguire ricerche senza distinzione tra maiuscole e minuscole con indexOf(), è possibile rendere entrambe le stringhe in maiuscolo o minuscolo. Ciò significa che, come nel secondo avviso(), JavaScript controllerà solo l'occorrenza della stringa che stai cercando, la maiuscola ignorata.

di riferimento, http://freewebdesigntutorials.com/javaScriptTutorials/jsStringObject/indexOfMethod.htm

67

Un'altra possibilità è quella di utilizzare il metodo di ricerca come segue:

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

Sembra più elegante poi convertire l'intera stringa in minuscolo e può essere più efficiente.
Con toLowerCase() codice hanno due passaggio sulla stringa, un passaggio è sulla intera stringa per convertirlo in minuscolo e un altro è cercare l'indice desiderato.
Con RegExp il codice ha un passaggio sulla stringa che sembra corrispondere all'indice desiderato.

Pertanto, in lunghe stringhe vi consiglio di utilizzare la versione RegExp (immagino che su brevi stringhe di questa efficienza arriva sul conto di creazione della RegExp oggetto però)

+7

+1, questa soluzione consente per l'espressione da memorizzare in una variabile –

+1

Questa è più vicina ad una risposta perché con test o match non è possibile ottenere l'indice – FlavorScape

+1

Questo è anche un po 'più veloce in base ai miei test: http://jsperf.com/case-insensitive-indexof –

1

E 'il 2016, e non c'è modo chiaro di come fare questo? Speravo in qualche copypasta. Avrò un andare.

Note di progettazione: Volevo ridurre al minimo l'utilizzo della memoria e quindi migliorare la velocità, quindi non c'è copia/mutazione di stringhe. Suppongo che V8 (e altri motori) possa ottimizzare questa funzione.

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

Il motivo per cui il nome:

  • dovrebbe avere IndexOf in nome
  • Non aggiungere un suffisso - si riferisce di al parametro
  • Non usare "CASEINSENSITIVE "Questo è tremendamente lungo
  • " naturale "è un buon candidato, perché i confronti di maiuscole/minuscole predefiniti non sono naturali per gli esseri umani in primo luogo.

Perché no ...:

  • toLowerCase() - potenziali ripetute chiamate toLowerCase sulla stessa corda.
  • RegExp - scomodo per cercare con variabile. Anche l'oggetto RegExp sta avendo scomodo per sfuggire caratteri
+0

Alito di aria fresca Qualcuno in realtà ha bisogno di tempo per riflettere attentamente e spiegare il ragionamento per il loro nome di funzione. un posto migliore proprio lì. –

0

Ecco il mio prendere:

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