finisce con JavaScript


1103

Come posso verificare se una stringa termina con un carattere particolare in JavaScript?

Esempio: ho una stringa

var str = "mystring#";

Voglio sapere se quella stringa sta finendo #. Come posso controllarlo?

  1. Esiste un endsWith()metodo in JavaScript?

  2. Una soluzione che ho è prendere la lunghezza della stringa e ottenere l'ultimo carattere e controllarlo.

È questo il modo migliore o c'è un altro modo?


5
Questo ha avuto modo di essere una questione connessa: stackoverflow.com/questions/646628/javascript-startswith
Hamish Grubijan

Risposte:


1764

AGGIORNAMENTO (24 novembre 2015):

Questa risposta è stata originariamente pubblicata nell'anno 2010 (SIX anni fa.) Quindi prendi nota di questi commenti perspicaci:


RISPOSTA ORIGINALE:

So che questa è una domanda di un anno ... ma ne ho bisogno anche io e ne ho bisogno per funzionare su più browser, quindi ... combinando la risposta e i commenti di tutti e semplificandola un po ':

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
  • Non crea una sottostringa
  • Utilizza la indexOffunzione nativa per risultati più rapidi
  • Salta i confronti non necessari utilizzando il secondo parametro di indexOfper saltare in avanti
  • Funziona in Internet Explorer
  • NO complicazioni Regex

Inoltre, se non ti piace inserire oggetti nei prototipi della struttura di dati nativi, ecco una versione autonoma:

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

EDIT: Come notato da @hamish nei commenti, se vuoi sbagliare sul lato sicuro e verificare se un'implementazione è già stata fornita, puoi semplicemente aggiungere un typeofcontrollo in questo modo:

if (typeof String.prototype.endsWith !== 'function') {
    String.prototype.endsWith = function(suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}

42
Aggiornamento per googler: sembra che ECMA6 abbia aggiunto questa funzione. L'articolo MDN mostra anche un polyfill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Shauna

2
@ lukas.pukenis salta alla fine e controlla solo un'istanza del suffisso alla fine. non importa se la stringa di ricerca appare altrove.
chakrit,

3
Aggiunta di un controllo per la situazione in cui l'argomento "suffisso" non è definito ": if (typeof String.prototype.endsWith! == 'function') {String.prototype.endsWith = function (suffix) {return this.indexOf (suffix , this.length - ((suffisso && suffix.length) || 0))! == -1;};}
Mandeep

2
Quali sono le complicazioni regex a cui ti riferivi?
IcedDante,

5
La creazione di sottostringhe non è costosa sui browser moderni; potrebbe essere stato nel 2010 quando questa risposta è stata pubblicata. Al giorno d'oggi, l' this.substr(-suffix.length) === suffixapproccio semplice è più veloce su Chrome, lo stesso su IE11 indexOfe solo il 4% più lento (fergetaboutit territorio) su Firefox: jsperf.com/endswith-stackoverflow/14 E più veloce su tutta la linea quando il risultato è falso: jsperf .com / limitswith-stackoverflow-when-false Naturalmente, con l'aggiunta di ES6 endsWith, il punto è controverso. :-)
TJ Crowder,

295
/#$/.test(str)

funzionerà su tutti i browser, non richiede patch scimmia Stringe non richiede la scansione dell'intera stringa come lastIndexOfquando non c'è corrispondenza.

Se si desidera abbinare una stringa costante che potrebbe contenere caratteri speciali di espressioni regolari, ad esempio '$', è possibile utilizzare quanto segue:

function makeSuffixRegExp(suffix, caseInsensitive) {
  return new RegExp(
      String(suffix).replace(/[$%()*+.?\[\\\]{|}]/g, "\\$&") + "$",
      caseInsensitive ? "i" : "");
}

e quindi puoi usarlo in questo modo

makeSuffixRegExp("a[complicated]*suffix*").test(str)

10
Questo è bello e semplice se stai cercando una sottostringa costante.
Warren Blanchet,

1
lastIndexOf esegue la scansione di tutta la stringa? Ho pensato che avrebbe cercato dall'inizio alla fine.
Tom Brito,

3
@TomBrito, lastIndexOfesegue la scansione dell'intera stringa solo se non trova corrispondenza o trova una corrispondenza all'inizio. Se c'è una corrispondenza alla fine, funziona in modo proporzionale alla lunghezza del suffisso. Sì, /asdf$/.test(str)restituisce true quando strtermina con "asdf".
Mike Samuel,

3
@ Tom Brito, è un'espressione regolare letterale. La sintassi è presa in prestito da Perl. Vedere developer.mozilla.org/en/Core_JavaScript_1.5_Guide/… o per un livello di dettaglio non necessario, vedere la sezione 7.8.5 delle specifiche del linguaggio EcmaScript.
Mike Samuel,

2
+1 per la compatibilità tra browser. Testato su Chrome 28.0.1500.72 m, Firefox 22.0 e IE9.
Adrien, il

91
  1. Sfortunatamente no.
  2. if( "mystring#".substr(-1) === "#" ) {}

14
@Anthony, um ... quindi usa .Length-1, qual è il problema? if (mystring.substr (mystring.length-1) === "#") {} funziona perfettamente in IE.
BrainSlugs83,

12
@ BrainSlugs83 - questo è esattamente il problema: la sintassi '.length-1' funziona in IE e la sintassi '-1' no. È qualcosa da tenere a mente, quindi fai +1 su Anthony per la mancia.
avramov,

2
Non potresti usare slice()? Funziona per me nel mio rapido test IE7.
alex

impazzito IE. quando morirà?
ahnbizcad,

67

Dai, questa è l' endsWithimplementazione corretta :

String.prototype.endsWith = function (s) {
  return this.length >= s.length && this.substr(this.length - s.length) == s;
}

l'utilizzo lastIndexOfcrea semplicemente cicli CPU non necessari se non vi è corrispondenza.


2
Concordato. Sento davvero che questa sia la soluzione più performante offerta in quanto ha il controllo di interruzioni / integrità precoci, è breve e concisa, è elegante (sovraccarico del prototipo di stringa) e la sottostringa sembra molto meno un colpo di risorsa rispetto alla rotazione del motore regex.
BrainSlugs83,

Piace anche questa soluzione. Solo il nome della funzione è scritto male. Dovrebbe essere "EndWith".
xmedeko,

3
@ BrainSlugs83 Sono passati un paio d'anni, ma ora questo metodo non è più veloce del metodo 'indexOf' menzionato sopra da chakrit, e in Safari è più lento del 30%! Ecco un test jsPerf per il caso di errore su una stringa di circa 50 caratteri: jsperf.com/endswithcomparison
Brent Faust,

4
Probabilmente dovrebbe usare ===però.
Timmmm,

56

Questa versione evita di creare una sottostringa e non usa espressioni regolari (alcune risposte regex qui funzioneranno; altre sono rotte):

String.prototype.endsWith = function(str)
{
    var lastIndex = this.lastIndexOf(str);
    return (lastIndex !== -1) && (lastIndex + str.length === this.length);
}

Se le prestazioni sono importanti per te, varrebbe la pena testare se lastIndexOfè effettivamente più veloce della creazione di una sottostringa o meno. (Potrebbe dipendere dal motore JS che stai usando ...) Potrebbe essere più veloce nel caso di abbinamento, e quando la stringa è piccola - ma quando la stringa è enorme deve guardare indietro attraverso tutto anche se non ci interessa davvero :(

Per controllare un singolo carattere, trovare la lunghezza e quindi usare charAtè probabilmente il modo migliore.


2
Se this.lastIndexOf () restituisce -1, puoi selezionare i casi in cui restituisce true dipendente da this.length e str.length. Aggiungi un test che lastIndexOf ()! = -1.
ebruchez,

1
Perché il metodo regex è rotto?
izb,

2
@izb: le risposte più vecchie delle mie che tentano di utilizzare str+"$"come regex sono interrotte, in quanto potrebbero non essere regex valide.
Jon Skeet,

26

Non ho visto l'apporach con il slicemetodo. Quindi lo lascio qui:

function endsWith(str, suffix) {
    return str.slice(-suffix.length) === suffix
}

1
Puoi semplificarlo un po 'di più: return str.slice (-1) === suffisso;
Erik K.

2
Questa è la risposta migliore Non sono sicuro del perché non abbia più voti.
nucleartide,

17
return this.lastIndexOf(str) + str.length == this.length;

non funziona nel caso in cui la lunghezza della stringa originale sia inferiore alla lunghezza della stringa di ricerca e la stringa di ricerca non venga trovata:

lastIndexOf restituisce -1, quindi aggiungi la lunghezza della stringa di ricerca e ti rimane la lunghezza della stringa originale.

Una possibile soluzione è

return this.length >= str.length && this.lastIndexOf(str) + str.length == this.length

30
Hai ottenuto il badge "Trovato un errore in una risposta di Jon Skeet". Vedi il tuo profilo per i dettagli.
Bobince

17

Da developer.mozilla.org String.prototype.endsWith ()

Sommario

Il endsWith()metodo determina se una stringa termina con i caratteri di un'altra stringa, restituendo vero o falso come appropriato.

Sintassi

str.endsWith(searchString [, position]);

parametri

  • searchString : i caratteri da cercare alla fine di questa stringa.

  • posizione : cerca all'interno di questa stringa come se questa stringa fosse solo così lunga; il valore predefinito è la lunghezza effettiva di questa stringa, bloccata nell'intervallo stabilito dalla lunghezza di questa stringa.

Descrizione

Questo metodo consente di determinare se una stringa termina o meno con un'altra stringa.

Esempi

var str = "To be, or not to be, that is the question.";

alert( str.endsWith("question.") );  // true
alert( str.endsWith("to be") );      // false
alert( str.endsWith("to be", 19) );  // true

specificazioni

ECMAScript Language Specification 6th Edition (ECMA-262)

Compatibilità del browser

Compatibilità del browser


10
if( ("mystring#").substr(-1,1) == '#' )

-- O --

if( ("mystring#").match(/#$/) )

8
String.prototype.endsWith = function(str) 
{return (this.match(str+"$")==str)}

String.prototype.startsWith = function(str) 
{return (this.match("^"+str)==str)}

spero che questo possa essere d'aiuto

var myStr =   Earth is a beautiful planet  ”;
var myStr2 = myStr.trim();  
//==“Earth is a beautiful planet”;

if (myStr2.startsWith(“Earth”)) // returns TRUE

if (myStr2.endsWith(“planet”)) // returns TRUE

if (myStr.startsWith(“Earth”)) 
// returns FALSE due to the leading spaces…

if (myStr.endsWith(“planet”)) 
// returns FALSE due to trailing spaces…

il modo tradizionale

function strStartsWith(str, prefix) {
    return str.indexOf(prefix) === 0;
}

function strEndsWith(str, suffix) {
    return str.match(suffix+"$")==suffix;
}

Devi scappare dalla tua stringa per sequenze di escape regex
Juan Mendes,

1
Le espressioni regolari sono lente anche nelle lingue veloci. Basta controllare la fine di una stringa.
Daniel Nuriyev,

8

Non ti conosco, ma:

var s = "mystring#";
s.length >= 1 && s[s.length - 1] == '#'; // will do the thing!

Perché espressioni regolari? Perché scherzare con il prototipo? substr? Andiamo, forza...


a volte è meglio quando è bagnato
Martin Capodici,

8

Solo un'altra rapida alternativa che ha funzionato come un incantesimo per me, usando regex:

// Would be equivalent to:
// "Hello World!".endsWith("World!")
"Hello World!".match("World!$") != null


6

Ho appena imparato a conoscere questa libreria di stringhe:

http://stringjs.com/

Includi il file js e usa la Svariabile in questo modo:

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

Può anche essere utilizzato in NodeJS installandolo:

npm install string

Quindi richiedendolo come Svariabile:

var S = require('string');

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


4
function strEndsWith(str,suffix) {
  var reguex= new RegExp(suffix+'$');

  if (str.match(reguex)!=null)
      return true;

  return false;
}

1
È meglio se spieghi perché il tuo codice risolve il problema. Vedi la guida Come rispondere .
brasofilo,

l'argomento suffisso dovrebbe essere scansionato per le espressioni regex che devono essere sfuggite. l'utilizzo di indexOf o lastIndexOf sembra essere un'opzione migliore.
vlad_tepesch,

Non funzionerà se il suffisso contiene uno di questi caratteri:. * +? ^ =!: $ {} () [] / \
gtournie,

4

Tante cose per un problema così piccolo, basta usare questa espressione regolare

var str = "mystring#";
var regex = /^.*#$/

if (regex.test(str)){
  //if it has a trailing '#'
}


4

Sono passati molti anni per questa domanda. Vorrei aggiungere un aggiornamento importante per gli utenti che desiderano utilizzare la risposta del chakrit più votata.

Le funzioni 'EndWith' sono già state aggiunte a JavaScript come parte di ECMAScript 6 (tecnologia sperimentale)

Riferiscilo qui: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith

Pertanto si consiglia vivamente di aggiungere il controllo dell'esistenza dell'implementazione nativa, come indicato nella risposta.


2
function check(str)
{
    var lastIndex = str.lastIndexOf('/');
    return (lastIndex != -1) && (lastIndex  == (str.length - 1));
}

2

Un modo per la prova futura e / o impedire la sovrascrittura del prototipo esistente sarebbe il test di verifica per vedere se è già stato aggiunto al prototipo String. Ecco la mia opinione sulla versione molto apprezzata non regex.

if (typeof String.endsWith !== 'function') {
    String.prototype.endsWith = function (suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}

L'uso if (!String.prototype.hasOwnProperty("endsWith"))è il modo migliore. Con typeof"MooTools e alcune delle altre librerie AJAX ti rovineranno", secondo "Crockford su JavaScript - Livello 7: ECMAScript 5: The New Parts", alle 15:50 min.
XP1,

2

La risposta accettata di @ chakrit è un modo solido per farlo da soli. Se, tuttavia, stai cercando una soluzione in pacchetto, ti consiglio di dare un'occhiata a underscore.string , come ha sottolineato @mlunoe. Usando underscore.string, il codice sarebbe:

function endsWithHash(str) {
  return _.str.endsWith(str, '#');
}

1

se non vuoi usare lasIndexOf o substr allora perché non guardare semplicemente la stringa nel suo stato naturale (es. un array)

String.prototype.endsWith = function(suffix) {
    if (this[this.length - 1] == suffix) return true;
    return false;
}

o come funzione autonoma

function strEndsWith(str,suffix) {
    if (str[str.length - 1] == suffix) return true;
    return false;
}

1
String.prototype.endWith = function (a) {
    var isExp = a.constructor.name === "RegExp",
    val = this;
    if (isExp === false) {
        a = escape(a);
        val = escape(val);
    } else
        a = a.toString().replace(/(^\/)|(\/$)/g, "");
    return eval("/" + a + "$/.test(val)");
}

// example
var str = "Hello";
alert(str.endWith("lo"));
alert(str.endWith(/l(o|a)/));

1

Dopo tutte quelle lunghe risposte, ho trovato questo pezzo di codice semplice e facile da capire!

function end(str, target) {
  return str.substr(-target.length) == target;
}

1

Questa è l'implementazione di EndWith: String.prototype.endsWith = function (str) { return this.length >= str.length && this.substr(this.length - str.length) == str; }


1

Questa è l'implementazione di endsWith:

String.prototype.endsWith = function (str) {
  return (this.length >= str.length) && (this.substr(this.length - str.length) === str);
}

0

Questo si basa sulla risposta accettata di @ charkit che consente a una matrice di stringhe o alla stringa di passare come argomento.

if (typeof String.prototype.endsWith === 'undefined') {
    String.prototype.endsWith = function(suffix) {
        if (typeof suffix === 'String') {
            return this.indexOf(suffix, this.length - suffix.length) !== -1;
        }else if(suffix instanceof Array){
            return _.find(suffix, function(value){
                console.log(value, (this.indexOf(value, this.length - value.length) !== -1));
                return this.indexOf(value, this.length - value.length) !== -1;
            }, this);
        }
    };
}

Ciò richiede underscorejs, ma probabilmente può essere regolato per rimuovere la dipendenza del trattino basso.


1
Questa è una cattiva soluzione, piuttosto se stai già usando il trattino basso dovresti aggiungere questo epeli.github.io/underscore.string alle tue dipendenze e usare la loro implementazione:_.str.endsWith
mlunoe,

0
if(typeof String.prototype.endsWith !== "function") {
    /**
     * String.prototype.endsWith
     * Check if given string locate at the end of current string
     * @param {string} substring substring to locate in the current string.
     * @param {number=} position end the endsWith check at that position
     * @return {boolean}
     *
     * @edition ECMA-262 6th Edition, 15.5.4.23
     */
    String.prototype.endsWith = function(substring, position) {
        substring = String(substring);

        var subLen = substring.length | 0;

        if( !subLen )return true;//Empty string

        var strLen = this.length;

        if( position === void 0 )position = strLen;
        else position = position | 0;

        if( position < 1 )return false;

        var fromIndex = (strLen < position ? strLen : position) - subLen;

        return (fromIndex >= 0 || subLen === -fromIndex)
            && (
                position === 0
                // if position not at the and of the string, we can optimise search substring
                //  by checking first symbol of substring exists in search position in current string
                || this.charCodeAt(fromIndex) === substring.charCodeAt(0)//fast false
            )
            && this.indexOf(substring, fromIndex) === fromIndex
        ;
    };
}

Benefici:

  • Questa versione non sta semplicemente riutilizzando indexOf.
  • Massime prestazioni su corde lunghe. Ecco un test di velocità http://jsperf.com/starts-ends-with/4
  • Pienamente compatibile con le specifiche ecmascript. Supera i test

0

Non usare espressioni regolari. Sono lenti anche nelle lingue veloci. Basta scrivere una funzione che controlla la fine di una stringa. Questa libreria ha belle esempi: groundjs / util.js . Fare attenzione ad aggiungere una funzione a String.prototype. Questo codice contiene dei bei esempi su come farlo: groundjs / prototype.js In generale, questa è una bella libreria a livello linguistico: groundjs Puoi anche dare un'occhiata a lodash


0

tutti sono esempi molto utili. AggiuntaString.prototype.endsWith = function(str) ci aiuterà a chiamare semplicemente il metodo per verificare se la nostra stringa finisce con essa o meno, anche regexp lo farà.

Ho trovato una soluzione migliore della mia. Grazie a tutti.


0

Per coffeescript

String::endsWith = (suffix) ->
  -1 != @indexOf suffix, @length - suffix.length
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.