Come verificare se una stringa “StartsWith” un’altra stringa?

Come scriverei l’equivalente di String.StartsWith in C # in JavaScript?

 var haystack = 'hello world'; var needle = 'he'; //haystack.startsWith(needle) == true 

Nota: questa è una vecchia domanda e, come indicato nei commenti, ECMAScript 2015 (ES6) ha introdotto il metodo .startsWith . Tuttavia, al momento della stesura di questo aggiornamento (2015) il supporto del browser è lungi dall’essere completo .

È ansible utilizzare il metodo String.prototype.startsWith() ECMAScript 6, ma non è ancora supportato in tutti i browser . Dovrai utilizzare uno shim / polyfill per aggiungerlo ai browser che non lo supportano. Creare un’implementazione conforms a tutti i dettagli esposti nelle specifiche è un po ‘complicato e la versione definita in questa risposta non funzionerà; se vuoi uno spessore fedele, usa entrambi:

  • String.prototype.starts di Matthias Bynens String.prototype.startsWith shim , o
  • Es6-shim , che riduce il più ansible le specifiche ES6, incluso String.prototype.startsWith .

Una volta che hai spulciato il metodo (o se stai solo supportando i browser e i motori JavaScript che già lo hanno), puoi usarlo in questo modo:

 "Hello World!".startsWith("He"); // true var haystack = "Hello world"; var prefix = 'orl'; haystack.startsWith(prefix); // false 

Un’altra alternativa con .lastIndexOf :

 haystack.lastIndexOf(needle, 0) === 0 

Questo guarda indietro nel haystack per una ricorrenza needle partire dall’indice 0 del haystack . In altre parole, controlla solo se il haystack inizia con l’ needle .

In linea di principio, questo dovrebbe avere vantaggi prestazionali rispetto ad altri approcci:

  • Non cerca l’intero haystack .
  • Non crea una nuova stringa temporanea e quindi la elimina immediatamente.
 data.substring(0, input.length) === input 

Senza una funzione di supporto, basta usare il metodo .test di regex:

 /^He/.test('Hello world') 

Per fare ciò con una stringa dynamic piuttosto che una con hardcoded (assumendo che la stringa non conterrà alcun carattere di controllo regexp):

 new RegExp('^' + needle).test(haystack) 

Dovresti controllare Esiste una funzione RegExp.escape in Javascript? se esiste la possibilità che i caratteri di controllo regexp compaiano nella stringa.

Volevo solo aggiungere la mia opinione su questo.

Penso che possiamo usare così:

 var haystack = 'hello world'; var needle = 'he'; if (haystack.indexOf(needle) == 0) { // Code if string starts with this substring } 

Soluzione migliore:

 function startsWith(str, word) { return str.lastIndexOf(word, 0) === 0; } startsWith("aaa", "a") true startsWith("aaa", "ab") false startsWith("abc", "abc") true startsWith("abc", "c") false startsWith("abc", "a") true startsWith("abc", "ba") false startsWith("abc", "ab") true 

Ed ecco le conclusioniCon se ne hai bisogno anche tu:

 function endsWith(str, word) { return str.indexOf(word, str.length - word.length) !== -1; } 

Per coloro che preferiscono il prototipo in String:

 String.prototype.startsWith || (String.prototype.startsWith = function(word) { return this.lastIndexOf(word, 0) === 0; }); String.prototype.endsWith || (String.prototype.endsWith = function(word) { return this.indexOf(word, this.length - word.length) !== -1; }); 

Uso:

 "abc".startsWith("ab") true "c".ensdWith("c") true 

Ecco un piccolo miglioramento della soluzione di CMS:

 if(!String.prototype.startsWith){ String.prototype.startsWith = function (str) { return !this.indexOf(str); } } "Hello World!".startsWith("He"); // true var data = "Hello world"; var input = 'He'; data.startsWith(input); // true 

Verifica se la funzione esiste già nel caso in cui un browser futuro la implementa nel codice nativo o se è implementata da un’altra libreria. Ad esempio, la libreria Prototype implementa già questa funzione.

Usando ! è leggermente più veloce e più conciso di === 0 anche se non è leggibile.

Controlla anche underscore.string.js . Viene fornito con una serie di utili metodi di test e manipolazione delle stringhe, incluso un metodo startsWith . Dai documenti:

startsWith _.startsWith(string, starts)

Questo metodo controlla se la string inizia con starts .

 _("image.gif").startsWith("image") => true 

Recentemente mi sono posto la stessa domanda.
Esistono molteplici soluzioni possibili, ecco 3 valide:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0 (aggiunto dopo aver visto la risposta di Mark Byers)
  • usando un loop:

     function startsWith(s,starter) { for (var i = 0,cur_c; i < starter.length; i++) { cur_c = starter[i]; if (s[i] !== starter[i]) { return false; } } return true; } 

Non ho incontrato l'ultima soluzione che rende l'uso di un ciclo.
Sorprendentemente questa soluzione supera i primi 3 con un margine significativo.
Ecco il test jsperf che ho eseguito per raggiungere questa conclusione: http://jsperf.com/startswith2/2

Pace

ps: ecmascript 6 (harmony) introduce un startsWith nativo startsWith metodo per le stringhe.
Pensa a quanto tempo sarebbe stato risparmiato se avessero pensato di includere questo metodo tanto necessario nella versione iniziale stessa.

Aggiornare

Come ha fatto notare Steve (il primo commento su questa risposta), la funzione personalizzata di cui sopra genererà un errore se il prefisso dato è più corto dell'intera stringa. Lo ha risolto e ha aggiunto un'ottimizzazione del ciclo che può essere visualizzata su http://jsperf.com/startswith2/4 .

Si noti che ci sono 2 ottimizzazioni del ciclo incluse in Steve, la prima delle due ha mostrato prestazioni migliori, quindi inserirò il seguente codice:

 function startsWith2(str, prefix) { if (str.length < prefix.length) return false; for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i) continue; return i < 0; } 

Dato che questo è così popolare, penso che valga la pena sottolineare che l’ECMA 6 prevede un’attuazione di questo metodo e che, in preparazione, si dovrebbe utilizzare il polyfill “ufficiale” per prevenire problemi e lacrime futuri.

Fortunatamente gli esperti di Mozilla ce ne forniscono uno:

https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith

 if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { position = position || 0; return this.indexOf(searchString, position) === position; }; } 

Si noti che questo ha il vantaggio di essere ignorato con garbo durante la transizione a ECMA 6.

La soluzione migliore è smettere di usare le chiamate alle librerie e riconoscere che stai lavorando con due array. Un’implementazione manuale è sia breve che anche più veloce di ogni altra soluzione che ho visto qui.

 function startsWith2(str, prefix) { if (str.length < prefix.length) return false; for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i) continue; return i < 0; } 

Per i confronti delle prestazioni (successo e fallimento), vedi http://jsperf.com/startswith2/4 . (Assicurati di controllare per le versioni successive che potrebbero aver trombato il mio.)

Ho appena saputo di questa libreria di stringhe:

http://stringjs.com/

Includere il file js e quindi utilizzare la variabile S questo modo:

 S('hi there').endsWith('hi there') 

Può anche essere utilizzato in NodeJS installandolo:

 npm install string 

Quindi richiedendolo come variabile S :

 var S = require('string'); 

La pagina web ha anche collegamenti a librerie di stringhe alternative, se questa non ti piace.

 var str = 'hol'; var data = 'hola mundo'; if (data.length >= str.length && data.substring(0, str.length) == str) return true; else return false; 

Basandomi sulle risposte qui, questa è la versione che sto usando, in quanto sembra offrire le migliori prestazioni basate sui test di JSPerf (ed è funzionalmente completa per quanto posso dire).

 if(typeof String.prototype.startsWith != 'function'){ String.prototype.startsWith = function(str){ if(str == null) return false; var i = str.length; if(this.length < i) return false; for(--i; (i >= 0) && (this[i] === str[i]); --i) continue; return i < 0; } } 

Questo era basato su startsWith2 da qui: http://jsperf.com/startswith2/6 . Ho aggiunto un piccolo aggiustamento per un piccolo miglioramento delle prestazioni, e da allora ho anche aggiunto un controllo per il fatto che la stringa di confronto è nullo o indefinito e l'ho convertita per aggiungerla al prototipo String usando la tecnica nella risposta di CMS.

Nota che questa implementazione non supporta il parametro "position" menzionato in questa pagina Mozilla Developer Network , ma che comunque non sembra far parte della proposta ECMAScript.

Stavo cercando le prestazioni, quindi ho eseguito le funzioni tramite jsperf. Ho testato le funzioni contro le stringhe di sobject e di ricerca di varie dimensioni e sembra che tutti i metodi esibiscano prestazioni diverse di input diversi; il modello generale è che le prestazioni si riducono con l’aumentare della lunghezza della stringa di ricerca.

Il vincitore generale risulta essere il metodo substr(ing) .

https://jsperf.com/javascript-string-startswith

Se stai lavorando con startsWith() e endsWith() devi fare attenzione a condurre gli spazi. Ecco un esempio completo:

 var str1 = " Your String Value Here.!! "; // Starts & ends with spaces if (str1.startsWith("Your")) { } // returns FALSE due to the leading spaces… if (str1.endsWith("Here.!!")) { } // returns FALSE due to trailing spaces… var str2 = str1.trim(); // Removes all spaces (and other white-space) from start and end of `str1`. if (str2.startsWith("Your")) { } // returns TRUE if (str2.endsWith("Here.!!")) { } // returns TRUE 

Puoi anche restituire tutti i membri di un array che iniziano con una stringa creando il tuo prototipo / estensione al prototipo dell’array, alias

 Array.prototype.mySearch = function (target) { if (typeof String.prototype.startsWith != 'function') { String.prototype.startsWith = function (str){ return this.slice(0, str.length) == str; }; } var retValues = []; for (var i = 0; i < this.length; i++) { if (this[i].startsWith(target)) { retValues.push(this[i]); } } return retValues; }; 

E per usarlo:

 var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster']; var myResult = myArray.mySearch('Hel'); // result -> Hello, Helium