se termine avec JavaScript

1103

Comment puis-je vérifier si une chaîne se termine par un caractère particulier en JavaScript?

Exemple: j'ai une chaîne

var str = "mystring#";

Je veux savoir si cette chaîne se termine par #. Comment puis-je le vérifier?

  1. Existe-t-il une endsWith()méthode en JavaScript?

  2. Une solution que j'ai est de prendre la longueur de la chaîne et d'obtenir le dernier caractère et de le vérifier.

Est-ce le meilleur moyen ou existe-t-il un autre moyen?

Bobby Kumar
la source

Réponses:

1764

MISE À JOUR (24 novembre 2015):

Cette réponse a été initialement publiée en 2010 (SIX ans en arrière). Veuillez donc prendre note de ces commentaires perspicaces:


RÉPONSE ORIGINALE:

Je sais que c'est une question vieille d'un an ... mais j'en ai aussi besoin et j'en ai besoin pour travailler sur plusieurs navigateurs donc ... en combinant la réponse et les commentaires de chacun et en simplifiant un peu:

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
  • Ne crée pas de sous-chaîne
  • Utilise la indexOffonction native pour des résultats plus rapides
  • Ignorez les comparaisons inutiles en utilisant le deuxième paramètre de indexOfpour avancer
  • Fonctionne dans Internet Explorer
  • AUCUNE complication Regex

De plus, si vous n'aimez pas bourrer les choses dans les prototypes de la structure de données native, voici une version autonome:

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

EDIT: Comme indiqué par @hamish dans les commentaires, si vous voulez vous tromper et vérifier si une implémentation a déjà été fournie, vous pouvez simplement ajouter une typeofvérification comme ceci:

if (typeof String.prototype.endsWith !== 'function') {
    String.prototype.endsWith = function(suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}
chakrit
la source
42
Mise à jour pour Googlers - On dirait que ECMA6 ajoute cette fonction. L'article MDN montre également un polyfill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Shauna
2
@ lukas.pukenis, il saute à la fin et ne vérifie qu'une seule instance du suffixe à la toute fin. peu importe si la chaîne de recherche apparaît ailleurs.
chakrit
3
Ajout d'une vérification de la situation lorsque l'argument "suffixe" n'est pas défini ": if (typeof String.prototype.endsWith! == 'function') {String.prototype.endsWith = function (suffix) {return this.indexOf (suffixe , this.length - ((suffixe && suffix.length) || 0))! == -1;};}
Mandeep
2
Quelles sont les complications regex dont vous avez parlé?
IcedDante
5
La création de sous-chaînes n'est pas chère sur les navigateurs modernes; c'était peut-être en 2010 lorsque cette réponse a été publiée. De nos jours, l' this.substr(-suffix.length) === suffixapproche simple est la plus rapide sur Chrome, la même sur IE11 que indexOf, et seulement 4% plus lente (territoire fergetaboutit) sur Firefox: jsperf.com/endswith-stackoverflow/14 Et plus rapide dans tous les cas lorsque le résultat est faux: jsperf .com / endswith-stackoverflow-when-false Bien sûr, avec l'ajout d'ES6 endsWith, le point est sans objet. :-)
TJ Crowder
295
/#$/.test(str)

fonctionnera sur tous les navigateurs, ne nécessite pas de correction de singe Stringet ne nécessite pas d'analyser la chaîne entière comme lastIndexOfil n'y a pas de correspondance.

Si vous souhaitez faire correspondre une chaîne constante qui peut contenir des caractères spéciaux d'expression régulière, tels que '$', vous pouvez utiliser les éléments suivants:

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

et vous pouvez l'utiliser comme ceci

makeSuffixRegExp("a[complicated]*suffix*").test(str)
Mike Samuel
la source
10
C'est agréable et simple si vous recherchez une sous-chaîne constante.
Warren Blanchet
1
lastIndexOf analyse toute la chaîne? Je pensais qu'il chercherait de la fin au début.
Tom Brito
3
@TomBrito, lastIndexOfanalyse la chaîne entière uniquement si elle ne trouve aucune correspondance, ou trouve une correspondance au début. S'il y a une correspondance à la fin, cela fonctionne proportionnellement à la longueur du suffixe. Oui, /asdf$/.test(str)donne vrai quand strse termine par "asdf".
Mike Samuel
3
@Tom Brito, c'est un littéral d'expression régulière. La syntaxe est empruntée à Perl. Voir developer.mozilla.org/en/Core_JavaScript_1.5_Guide/… ou pour un niveau de détail inutile, voir la section 7.8.5 de la spécification du langage EcmaScript.
Mike Samuel
2
+1 pour la compatibilité entre les navigateurs. Testé sur Chrome 28.0.1500.72 m, Firefox 22.0 et IE9.
Adrien Be
91
  1. Malheureusement non.
  2. if( "mystring#".substr(-1) === "#" ) {}
Phillip B Oldham
la source
14
@Anthony, euh ... alors utilisez .Length-1, quel est le problème? if (mystring.substr (mystring.length-1) === "#") {} fonctionne très bien dans IE.
BrainSlugs83
12
@ BrainSlugs83 - c'est exactement le problème: la syntaxe '.length-1' fonctionne dans IE, et la syntaxe '-1' ne fonctionne pas. C'est quelque chose à garder à l'esprit, alors +1 à Anthony pour le conseil.
avramov
2
Tu ne pourrais pas utiliser slice()? Cela fonctionne pour moi dans mon test rapide IE7.
alex
paniquer IE. quand mourra-t-elle?
ahnbizcad
67

Allez, c'est la bonne endsWithmise en œuvre:

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

l'utilisation lastIndexOfcrée simplement des boucles CPU inutiles s'il n'y a pas de correspondance.

Oskar Liljeblad
la source
2
D'accord. J'ai vraiment l'impression que c'est la solution la plus performante offerte car elle a un avortement précoce / un contrôle d'intégrité, elle est courte et concise, elle est élégante (surchargeant le prototype de chaîne) et la sous-chaîne semble être beaucoup moins affectée par les ressources que la rotation du moteur regex.
BrainSlugs83
J'aime aussi cette solution. Seul le nom de la fonction est mal orthographié. Doit être "termine avec".
xmedeko
3
@ BrainSlugs83 Cela fait quelques années, mais maintenant cette méthode n'est pas plus rapide que la méthode 'indexOf' mentionnée ci-dessus par chakrit, et sous Safari, elle est 30% plus lente! Voici un test jsPerf pour le cas d'échec sur une chaîne d'environ 50 caractères: jsperf.com/endswithcomparison
Brent Faust
4
Devrait probablement utiliser ===cependant.
Timmmm
56

Cette version évite de créer une sous-chaîne et n'utilise pas d'expressions régulières (certaines réponses d'expression régulière fonctionneront ici, d'autres sont cassées):

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

Si les performances sont importantes pour vous, il vaudrait la peine de vérifier si lastIndexOf sont réellement plus rapides que la création d'une sous-chaîne ou non. (Cela peut dépendre du moteur JS que vous utilisez ...) Cela peut être plus rapide dans le cas correspondant, et lorsque la chaîne est petite - mais lorsque la chaîne est énorme, elle doit regarder en arrière, même mais on s'en fout vraiment :(

Pour vérifier un seul caractère, trouver la longueur puis l'utiliser charAtest probablement le meilleur moyen.

Jon Skeet
la source
2
Si this.lastIndexOf () renvoie -1, vous pouvez atteindre les cas où il retourne true dépend de this.length et str.length. Ajoutez un test qui lastIndexOf ()! = -1.
ebruchez
1
Pourquoi la méthode regex est-elle cassée?
izb
2
@izb: Les réponses qui sont plus anciennes que la mienne et qui tentent de l'utiliser str+"$"comme expression régulière sont brisées, car elles peuvent ne pas être des expressions régulières valides.
Jon Skeet
26

Je n'ai pas vu d'approches avec la sliceméthode. Je laisse donc ça ici:

function endsWith(str, suffix) {
    return str.slice(-suffix.length) === suffix
}
Nikita Koksharov
la source
1
Vous pouvez le simplifier un peu plus: return str.slice (-1) === suffix;
Erik K.
2
C'est la meilleure réponse. Je ne sais pas pourquoi il n'a pas plus de votes positifs.
Nucleartide
17
return this.lastIndexOf(str) + str.length == this.length;

ne fonctionne pas dans le cas où la longueur de la chaîne d'origine est inférieure de un à la longueur de la chaîne de recherche et la chaîne de recherche est introuvable:

lastIndexOf renvoie -1, puis vous ajoutez la longueur de la chaîne de recherche et vous vous retrouvez avec la longueur de la chaîne d'origine.

Une solution possible est

return this.length >= str.length && this.lastIndexOf(str) + str.length == this.length
user73745
la source
30
Vous avez gagné le badge «Trouvé une erreur dans une réponse de Jon Skeet». Consultez votre profil pour plus de détails.
bobince
17

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

Sommaire

La endsWith()méthode détermine si une chaîne se termine par les caractères d'une autre chaîne, renvoyant vrai ou faux selon le cas.

Syntaxe

str.endsWith(searchString [, position]);

Paramètres

  • searchString : les caractères à rechercher à la fin de cette chaîne.

  • position : Rechercher dans cette chaîne comme si cette chaîne n'était que longue; par défaut, la longueur réelle de cette chaîne, fixée dans la plage établie par la longueur de cette chaîne.

La description

Cette méthode vous permet de déterminer si une chaîne se termine ou non par une autre chaîne.

Exemples

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

Caractéristiques

ECMAScript Language Specification 6th Edition (ECMA-262)

Compatibilité du navigateur

Compatibilité du navigateur

Aniket Kulkarni
la source
10
if( ("mystring#").substr(-1,1) == '#' )

-- Ou --

if( ("mystring#").match(/#$/) )
duckyflip
la source
8
String.prototype.endsWith = function(str) 
{return (this.match(str+"$")==str)}

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

J'espère que ça aide

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…

la manière traditionnelle

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

function strEndsWith(str, suffix) {
    return str.match(suffix+"$")==suffix;
}
Mohammed Rafeeq
la source
Vous devez échapper à votre chaîne pour les séquences d'échappement regex
Juan Mendes
1
Les expressions régulières sont lentes même dans les langages rapides. Vérifiez simplement la fin d'une chaîne.
Daniel Nouriev
8

Je ne sais pas pour vous, mais:

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

Pourquoi des expressions régulières? Pourquoi jouer avec le prototype? substr? Allons y...

Tici
la source
'parfois c'est mieux quand c'est MOUILLÉ
Martin Capodici
8

Juste une autre alternative rapide qui a fonctionné comme un charme pour moi, en utilisant regex:

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

Si vous utilisez lodash :

_.endsWith('abc', 'c'); // true

Si vous n'utilisez pas lodash, vous pouvez emprunter à sa source .

Dheeraj Vepakomma
la source
6

Je viens d'apprendre cette bibliothèque de chaînes:

http://stringjs.com/

Incluez le fichier js, puis utilisez la Svariable comme ceci:

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

Il peut également être utilisé dans NodeJS en l'installant:

npm install string

Le nécessitant ensuite comme Svariable:

var S = require('string');

La page Web contient également des liens vers d'autres bibliothèques de chaînes, si celle-ci ne vous convient pas.

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

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

  return false;
}
Tabish Usman
la source
1
Il vaut mieux expliquer pourquoi votre code résout le problème. Voir le guide Comment répondre .
brasofilo
l'argument suffixe doit être analysé pour les expressions d'expression régulière qui doivent être échappées. utiliser indexOf ou lastIndexOf semble être une meilleure option.
vlad_tepesch
Cela ne fonctionnera pas si le suffixe contient l'un de ces caractères:. * +? ^ =!: $ {} () [] / \
gtournie
4

Tant de choses pour un si petit problème, utilisez simplement cette expression régulière

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

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

LahiruBandara
la source
4

Cela fait de nombreuses années pour cette question. Permettez-moi d'ajouter une mise à jour importante pour les utilisateurs qui souhaitent utiliser la réponse du chakrit la plus votée.

Les fonctions 'endsWith' sont déjà ajoutées à JavaScript dans le cadre d'ECMAScript 6 (technologie expérimentale)

Référez-le ici: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith

Par conséquent, il est fortement recommandé d'ajouter une vérification de l'existence d'une implémentation native comme mentionné dans la réponse.

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

Un moyen de pérenniser et / ou d'empêcher l'écrasement du prototype existant serait de vérifier le test pour voir s'il a déjà été ajouté au prototype String. Voici mon point de vue sur la version très appréciée non regex.

if (typeof String.endsWith !== 'function') {
    String.prototype.endsWith = function (suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}
Dan Doyon
la source
L'utilisation if (!String.prototype.hasOwnProperty("endsWith"))est la meilleure façon. Avec typeof, "MooTools et certaines autres bibliothèques AJAX vont vous gâcher", selon "Crockford on JavaScript - Level 7: ECMAScript 5: The New Parts", à 15:50 min.
XP1
2

La réponse acceptée de @ chakrit est un moyen solide de le faire vous-même. Si, cependant, vous recherchez une solution packagée, je vous recommande de jeter un œil à underscore.string , comme l'a souligné @mlunoe. En utilisant underscore.string, le code serait:

function endsWithHash(str) {
  return _.str.endsWith(str, '#');
}
rmehlinger
la source
1

si vous ne voulez pas utiliser lasIndexOf ou substr, alors pourquoi ne pas simplement regarder la chaîne dans son état naturel (c'est-à-dire un tableau)

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

ou en tant que fonction autonome

function strEndsWith(str,suffix) {
    if (str[str.length - 1] == suffix) return true;
    return false;
}
user511941
la source
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)/));
Ebubekir Dirican
la source
1

Après tout ce long décompte de réponses, j'ai trouvé ce morceau de code simple et facile à comprendre!

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

Ceci est la mise en œuvre de endsWith: String.prototype.endsWith = function (str) { return this.length >= str.length && this.substr(this.length - str.length) == str; }

Singh123
la source
1

Il s'agit de la mise en œuvre de endsWith:

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

Cela s'appuie sur la réponse acceptée de @ charkit permettant à un tableau de chaînes ou à une chaîne de passer en argument.

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

Cela nécessite des traits de soulignement - mais peut probablement être ajusté pour supprimer la dépendance de soulignement.

Matthew Brown
la source
1
C'est une mauvaise solution, plutôt si vous utilisez déjà le soulignement, vous devez ajouter cette epeli.github.io/underscore.string à vos dépendances et utiliser leur implémentation:_.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
        ;
    };
}

Avantages:

  • Cette version ne se contente pas de réutiliser indexOf.
  • Meilleure performance sur les cordes longues. Voici un test de vitesse http://jsperf.com/starts-ends-with/4
  • Entièrement compatible avec la spécification ecmascript. Il passe les tests
termi
la source
0

N'utilisez pas d'expressions régulières. Ils sont lents même dans les langues rapides. Écrivez simplement une fonction qui vérifie la fin d'une chaîne. Cette bibliothèque a de bons exemples: groundjs / util.js . Soyez prudent en ajoutant une fonction à String.prototype. Ce code a de bons exemples de comment le faire: groundjs / prototype.js En général, c'est une belle bibliothèque au niveau du langage: groundjs Vous pouvez également jeter un œil à lodash

Daniel Nouriev
la source
0

tous sont des exemples très utiles. AjouterString.prototype.endsWith = function(str) nous aidera à simplement appeler la méthode pour vérifier si notre chaîne se termine par ou non, bien regexp le fera également.

J'ai trouvé une meilleure solution que la mienne. Merci tout le monde.

Bobby Kumar
la source
0

Pour coffeescript

String::endsWith = (suffix) ->
  -1 != @indexOf suffix, @length - suffix.length
Quanlong
la source