endet mit JavaScript

1103

Wie kann ich überprüfen, ob eine Zeichenfolge in JavaScript mit einem bestimmten Zeichen endet?

Beispiel: Ich habe eine Zeichenfolge

var str = "mystring#";

Ich möchte wissen, ob diese Zeichenfolge mit endet #. Wie kann ich das überprüfen?

  1. Gibt es eine endsWith()Methode in JavaScript?

  2. Eine Lösung, die ich habe, besteht darin, die Länge der Zeichenfolge zu nehmen, das letzte Zeichen zu erhalten und es zu überprüfen.

Ist das der beste Weg oder gibt es einen anderen Weg?

Bobby Kumar
quelle

Antworten:

1764

UPDATE (24. November 2015):

Diese Antwort wurde ursprünglich im Jahr 2010 (vor sechs Jahren) veröffentlicht. Bitte beachten Sie diese aufschlussreichen Kommentare:


URSPRÜNGLICHE ANTWORT:

Ich weiß, dass dies eine einjährige Frage ist ... aber ich brauche sie auch und sie muss browserübergreifend funktionieren, also ... die Antworten und Kommentare aller kombinieren und ein wenig vereinfachen:

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
  • Erstellt keinen Teilstring
  • Verwendet die native indexOfFunktion für schnellste Ergebnisse
  • Überspringen Sie unnötige Vergleiche mit dem zweiten Parameter von indexOf, um fortzufahren
  • Funktioniert im Internet Explorer
  • KEINE Regex-Komplikationen

Wenn Sie es nicht mögen, Dinge in die Prototypen der nativen Datenstruktur zu stopfen, finden Sie hier eine eigenständige Version:

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

BEARBEITEN: Wie von @hamish in den Kommentaren erwähnt, können Sie, wenn Sie auf der sicheren Seite irren und prüfen möchten, ob bereits eine Implementierung bereitgestellt wurde, einfach eine typeofPrüfung wie folgt hinzufügen :

if (typeof String.prototype.endsWith !== 'function') {
    String.prototype.endsWith = function(suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}
Chakrit
quelle
42
Update für Googler - ECMA6 fügt diese Funktion anscheinend hinzu. Der MDN-Artikel zeigt auch eine Polyfüllung. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Shauna
2
@ lukas.pukenis es springt zum Ende und überprüft nur eine Instanz des Suffixes ganz am Ende. Es spielt keine Rolle, ob die Suchzeichenfolge an anderer Stelle angezeigt wird.
Chakrit
3
Hinzufügen einer Prüfung für die Situation, in der das Argument "Suffix" nicht definiert ist ": if (typeof String.prototype.endsWith! == 'function') {String.prototype.endsWith = function (Suffix) {return this.indexOf (Suffix) , this.length - ((Suffix && Suffix.length) || 0))! == -1;};}
Mandeep
2
Was sind die Regex-Komplikationen, auf die Sie sich bezogen haben?
IcedDante
5
Das Erstellen von Teilzeichenfolgen ist in modernen Browsern nicht teuer. Möglicherweise war es 2010, als diese Antwort veröffentlicht wurde. this.substr(-suffix.length) === suffixHeutzutage ist der einfache Ansatz in Chrome am schnellsten, in IE11 derselbe indexOfund in Firefox nur 4% langsamer (Fergetaboutit-Gebiet): jsperf.com/endswith-stackoverflow/14 Und auf der ganzen Linie schneller, wenn das Ergebnis falsch ist: jsperf .com / endswith-stackoverflow-when-false Natürlich endsWithist der Punkt beim Hinzufügen von ES6 umstritten . :-)
TJ Crowder
295
/#$/.test(str)

funktioniert in allen Browsern, erfordert kein Affen-Patching Stringund erfordert nicht das Scannen der gesamten Zeichenfolge, wie dies der lastIndexOfFall ist, wenn keine Übereinstimmung vorliegt.

Wenn Sie mit einer konstanten Zeichenfolge übereinstimmen möchten, die möglicherweise Sonderzeichen für reguläre Ausdrücke enthält, z. B. '$', können Sie Folgendes verwenden:

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

und dann können Sie es so verwenden

makeSuffixRegExp("a[complicated]*suffix*").test(str)
Mike Samuel
quelle
10
Dies ist schön und einfach, wenn Sie nach einem konstanten Teilstring suchen.
Warren Blanchet
1
lastIndexOf scannt den gesamten String? Ich dachte, es würde vom Ende bis zum Anfang suchen.
Tom Brito
3
@TomBrito lastIndexOfscannt die gesamte Zeichenfolge nur, wenn keine Übereinstimmung gefunden wird oder wenn am Anfang eine Übereinstimmung gefunden wird. Wenn am Ende eine Übereinstimmung vorliegt, funktioniert diese proportional zur Länge des Suffix. Ja, /asdf$/.test(str)ergibt wahr, wenn mit strendet "asdf".
Mike Samuel
3
@ Tom Brito, es ist ein Literal mit regulären Ausdrücken. Die Syntax ist von Perl entlehnt. Siehe developer.mozilla.org/en/Core_JavaScript_1.5_Guide/... oder für eine unnötige Detailebene, siehe Abschnitt 7.8.5 der EcmaScript - Sprachspezifikation.
Mike Samuel
2
+1 für die browserübergreifende Kompatibilität. Getestet auf Chrome 28.0.1500.72 m, Firefox 22.0 und IE9.
Adrien Be
91
  1. Leider nicht.
  2. if( "mystring#".substr(-1) === "#" ) {}
Phillip B. Oldham
quelle
14
@Anthony, ähm ... also benutze .Length-1, was ist das Problem? if (mystring.substr (mystring.length-1) === "#") {} funktioniert im IE einwandfrei.
BrainSlugs83
12
@ BrainSlugs83 - genau das ist das Problem: Die Syntax '.length-1' funktioniert im IE und die Syntax '-1' nicht. Es ist etwas zu beachten, also +1 an Anthony für den Tipp.
Avramov
2
Könnten Sie nicht verwenden slice()? Es funktioniert für mich in meinem schnellen IE7-Test.
alex
freaken IE. wann wird es sterben
Ahnbizcad
67

Komm schon, das ist die richtige endsWithImplementierung:

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

Die Verwendung von lastIndexOferzeugt nur unnötige CPU-Schleifen, wenn keine Übereinstimmung vorliegt.

Oskar Liljeblad
quelle
2
Einverstanden. Ich bin wirklich der Meinung, dass dies die leistungsstärkste Lösung ist, die angeboten wird, da sie frühzeitige Abbruch- / Vernunftprüfungen bietet, kurz und prägnant ist, elegant (Überlastung des String-Prototyps) und Teilzeichenfolgen weniger als ein Ressourcen-Hit erscheinen als das Hochfahren der Regex-Engine.
BrainSlugs83
Auch wie diese Lösung. Nur der Funktionsname ist falsch geschrieben. Sollte "endet mit" sein.
Xmedeko
3
@ BrainSlugs83 Es ist ein paar Jahre her, aber jetzt ist diese Methode nicht schneller als die oben von chakrit erwähnte 'indexOf'-Methode und unter Safari 30% langsamer! Hier ist ein jsPerf-Test für den Fehlerfall über eine Zeichenfolge von etwa 50 Zeichen: jsperf.com/endswithcomparison
Brent Faust
4
Sollte aber wohl verwenden ===.
Timmmm
56

Diese Version vermeidet das Erstellen eines Teilstrings und verwendet keine regulären Ausdrücke (einige Regex-Antworten hier funktionieren; andere sind fehlerhaft):

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

Wenn Ihnen die Leistung wichtig ist, sollten Sie testen, ob sie lastIndexOftatsächlich schneller ist als das Erstellen eines Teilstrings. (Es kann durchaus von der JS-Engine abhängen, die Sie verwenden ...) Im passenden Fall kann es durchaus schneller sein, und wenn die Zeichenfolge klein ist - aber wenn die Zeichenfolge groß ist, muss sie sogar das Ganze noch einmal durchsehen obwohl es uns eigentlich egal ist :(

Um ein einzelnes Zeichen zu überprüfen, charAtist es wahrscheinlich der beste Weg , die Länge zu finden und dann zu verwenden .

Jon Skeet
quelle
2
Wenn this.lastIndexOf () -1 zurückgibt, können Sie Fälle treffen, in denen true zurückgegeben wird, abhängig von this.length und str.length. Fügen Sie einen Test hinzu, der lastIndexOf ()! = -1.
Ebruchez
1
Warum ist die Regex-Methode kaputt?
izb
2
@izb: Die Antworten, die älter als meine str+"$"sind und als reguläre Ausdrücke verwendet werden sollen, sind fehlerhaft, da sie möglicherweise keine gültigen regulären Ausdrücke sind.
Jon Skeet
26

Ansatz mit sliceMethode nicht gesehen. Also lasse ich es einfach hier:

function endsWith(str, suffix) {
    return str.slice(-suffix.length) === suffix
}
Nikita Koksharov
quelle
1
Sie können es etwas vereinfachen: return str.slice (-1) === Suffix;
Erik K.
2
Dies ist die beste Antwort. Ich bin mir nicht sicher, warum es nicht mehr Upvotes gibt.
Nuklearflut
17
return this.lastIndexOf(str) + str.length == this.length;

funktioniert nicht in dem Fall, in dem die ursprüngliche Zeichenfolgenlänge um eins kleiner als die Länge der Suchzeichenfolge ist und die Suchzeichenfolge nicht gefunden wird:

lastIndexOf gibt -1 zurück, dann fügen Sie die Länge der Suchzeichenfolge hinzu und die Länge der ursprünglichen Zeichenfolge bleibt erhalten.

Eine mögliche Lösung ist

return this.length >= str.length && this.lastIndexOf(str) + str.length == this.length
user73745
quelle
30
Sie haben das Abzeichen "In einer Antwort von Jon Skeet einen Fehler gefunden" erhalten. Einzelheiten finden Sie in Ihrem Profil.
Bobince
17

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

Zusammenfassung

Die endsWith()Methode bestimmt, ob eine Zeichenfolge mit den Zeichen einer anderen Zeichenfolge endet, und gibt je nach Bedarf true oder false zurück.

Syntax

str.endsWith(searchString [, position]);

Parameter

  • searchString : Die Zeichen, nach denen am Ende dieser Zeichenfolge gesucht werden soll.

  • Position : Suchen Sie in dieser Zeichenfolge, als wäre diese Zeichenfolge nur so lang. Der Standardwert ist die tatsächliche Länge dieser Zeichenfolge, die innerhalb des durch die Länge dieser Zeichenfolge festgelegten Bereichs geklemmt wird.

Beschreibung

Mit dieser Methode können Sie bestimmen, ob eine Zeichenfolge mit einer anderen Zeichenfolge endet oder nicht.

Beispiele

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

Spezifikationen

ECMAScript-Sprachspezifikation 6. Ausgabe (ECMA-262)

Browser-Kompatibilität

Browser-Kompatibilität

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

-- Oder --

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

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

ich hoffe das hilft

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…

der traditionelle Weg

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

function strEndsWith(str, suffix) {
    return str.match(suffix+"$")==suffix;
}
Mohammed Rafeeq
quelle
Sie müssen Ihre Zeichenfolge für Regex-Escape-Sequenzen entkommen
Juan Mendes
1
Reguläre Ausdrücke sind selbst in schnellen Sprachen langsam. Überprüfen Sie einfach das Ende einer Zeichenfolge.
Daniel Nuriyev
8

Ich weiß nichts über dich, aber:

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

Warum reguläre Ausdrücke? Warum mit dem Prototyp herumspielen? substr? Komm schon...

Tici
quelle
Weil es manchmal besser ist, wenn es nass ist
Martin Capodici
8

Nur eine weitere schnelle Alternative, die mit Regex wie ein Zauber für mich funktioniert hat:

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

Wenn Sie lodash verwenden :

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

Wenn Sie lodash nicht verwenden, können Sie es von seiner Quelle ausleihen .

Dheeraj Vepakomma
quelle
6

Ich habe gerade von dieser String-Bibliothek erfahren:

http://stringjs.com/

Fügen Sie die js-Datei ein und verwenden Sie die SVariable wie folgt :

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

Es kann auch in NodeJS verwendet werden, indem es installiert wird:

npm install string

Dann benötigen Sie es als SVariable:

var S = require('string');

Die Webseite enthält auch Links zu alternativen Zeichenfolgenbibliotheken, falls Sie dies nicht möchten.

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

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

  return false;
}
Tabish Usman
quelle
1
Es ist besser, wenn Sie erklären, warum Ihr Code das Problem löst. Siehe die Anleitung zur Beantwortung .
Brasofilo
Das Suffix-Argument sollte nach regulären Ausdrücken durchsucht werden, die maskiert werden müssen. Die Verwendung von indexOf oder lastIndexOf scheint eine bessere Option zu sein.
vlad_tepesch
Es wird nicht funktionieren, wenn das Suffix eines dieser Zeichen enthält :. * +? ^ = !: $ {} () [] / \
Gtournie
4

So viele Dinge für ein so kleines Problem, verwenden Sie einfach diesen regulären Ausdruck

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

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

LahiruBandara
quelle
4

Es ist viele Jahre her für diese Frage. Lassen Sie mich ein wichtiges Update für die Benutzer hinzufügen, die die Antwort des am meisten bewerteten Chakrits verwenden möchten.

Die Funktionen 'Enden mit' wurden bereits als Teil von ECMAScript 6 (experimentelle Technologie) zu JavaScript hinzugefügt.

Verweisen Sie hier: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith

Daher wird dringend empfohlen, die in der Antwort erwähnte Überprüfung auf das Vorhandensein einer nativen Implementierung hinzuzufügen.

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

Eine Möglichkeit zur Zukunftssicherung und / oder zum Verhindern des Überschreibens eines vorhandenen Prototyps wäre eine Testprüfung, um festzustellen, ob dieser bereits zum String-Prototyp hinzugefügt wurde. Hier ist meine Sicht auf die hoch bewertete Version ohne Regex.

if (typeof String.endsWith !== 'function') {
    String.prototype.endsWith = function (suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}
Dan Doyon
quelle
Verwenden if (!String.prototype.hasOwnProperty("endsWith"))ist der beste Weg. Mit typeof"MooTools und einige der anderen AJAX-Bibliotheken werden Sie vermasseln", laut "Crockford on JavaScript - Level 7: ECMAScript 5: Die neuen Teile", um 15:50 min.
XP1
2

Die akzeptierte Antwort von @ chakrit ist eine solide Möglichkeit, dies selbst zu tun. Wenn Sie jedoch nach einer Paketlösung suchen, empfehlen wir Ihnen, einen Blick auf underscore.string zu werfen, wie @mlunoe hervorhob. Bei Verwendung von underscore.string lautet der Code:

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

Wenn Sie lasIndexOf oder substr nicht verwenden möchten, sehen Sie sich den String einfach in seinem natürlichen Zustand an (z. B. ein Array).

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

oder als eigenständige Funktion

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

Nach all den langen Antworten fand ich diesen Code einfach und leicht zu verstehen!

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

Dies ist die Implementierung von EndsWith: String.prototype.endsWith = function (str) { return this.length >= str.length && this.substr(this.length - str.length) == str; }

Singh123
quelle
1

Dies ist die Implementierung von endsWith:

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

Dies baut auf der akzeptierten Antwort von @ charkit auf, sodass entweder ein Array von Zeichenfolgen oder eine Zeichenfolge als Argument übergeben werden kann.

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

Dies erfordert Unterstriche - kann aber wahrscheinlich angepasst werden, um die Unterstrichabhängigkeit zu entfernen.

Matthew Brown
quelle
1
Dies ist eine schlechte Lösung. Wenn Sie bereits einen Unterstrich verwenden, sollten Sie diesen epeli.github.io/underscore.string zu Ihren Abhängigkeiten hinzufügen und deren Implementierung verwenden:_.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
        ;
    };
}

Leistungen:

  • Diese Version verwendet indexOf nicht nur wieder.
  • Größte Leistung auf langen Saiten. Hier ist ein Geschwindigkeitstest http://jsperf.com/starts-ends-with/4
  • Voll kompatibel mit der Ecmascript-Spezifikation. Es besteht die Tests
termi
quelle
0

Verwenden Sie keine regulären Ausdrücke. Sie sind selbst in schnellen Sprachen langsam. Schreiben Sie einfach eine Funktion, die das Ende einer Zeichenfolge überprüft. Diese Bibliothek hat schöne Beispiele: groundjs / util.js . Seien Sie vorsichtig, wenn Sie String.prototype eine Funktion hinzufügen. Dieser Code enthält nette Beispiele dafür: groundjs / prototype.js Im Allgemeinen ist dies eine nette Bibliothek auf Sprachebene : groundjs Sie können sich auch lodash ansehen

Daniel Nuriyev
quelle
0

Alle von ihnen sind sehr nützliche Beispiele. HinzufügenString.prototype.endsWith = function(str) hilft uns, die Methode einfach aufzurufen, um zu überprüfen, ob unsere Zeichenfolge damit endet oder nicht. Nun, Regexp wird es auch tun.

Ich habe eine bessere Lösung gefunden als meine. Vielen Dank an alle.

Bobby Kumar
quelle
0

Für Coffeescript

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