string - endsWith i JavaScript
Hur kan jag kontrollera om en sträng slutar med ett visst tecken i JavaScript?
Exempel: Jag har en sträng
var str = "mystring#";
Jag vill veta om den strängen slutar med #. Hur kan jag kolla det?
Finns det en
endsWith()-metod i JavaScript?En lösning jag har är att ta längden på strängen och få det sista tecknet och kolla det.
Är detta det bästa sättet eller finns det något annat sätt?
Svar #1
UPPDATERING (24 nov 2015):
Detta svar publicerades ursprungligen år 2010 (SEX år sedan), så var god uppmärksamma på dessa insiktsfulla kommentarer:
- Shauna -
Uppdatering för Googlers - Det ser ut som att ECMA6 lägger till denna funktion. MDN-artikeln visar också en polyfill. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
- T.J. Crowder -
Att skapa delsträngar är inte dyrt i moderna webbläsare; det kan mycket väl ha varit det år 2010 när detta svar publicerades. Nuförtiden är den enkla
this.substr(-suffix.length) === suffix-metoden snabbast i Chrome, samma hastighet i IE11 som indexOf, och bara 4% långsammare (försumbar skillnad) i Firefox: https://jsben.ch/OJzlM Och snabbare överlag när resultatet är falskt: jsperf.com/endswith-stackoverflow-when-false Naturligtvis, med ES6 som lägger till endsWith, är frågan ointressant. :-)
ORIGINALT SVAR:
Jag vet att detta är en fråga från förra året... men jag behöver det här också och jag behöver att det fungerar i olika webbläsare så... genom att kombinera allas svar och kommentarer och förenkla det lite:
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
- Skapar inte en delsträng
- Använder den inbyggda
indexOf-funktionen för snabbast resultat - Hoppa över onödiga jämförelser genom att använda den andra parametern i
indexOfför att hoppa framåt - Fungerar i Internet Explorer
- INGA Regex-komplikationer
Dessutom, om du inte gillar att trycka in saker i prototyperna för inbyggda datastrukturer, här är en fristående version:
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
REDIGERA: Som @hamish påpekade i kommentarerna, om du vill vara på den säkra sidan och kontrollera om en implementation redan har tillhandahållits, kan du bara lägga till en typeof-kontroll så här:
if (typeof String.prototype.endsWith !== 'function') {
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
}
Svar #2
/#$/.test(str)
kommer att fungera på alla webbläsare, kräver ingen monkey patching av String, och kräver inte att hela strängen skannas som lastIndexOf gör när det inte finns någon matchning.
Om du vill matcha en konstant sträng som kan innehålla specialtecken för reguljära uttryck, såsom '$', kan du använda följande:
function makeSuffixRegExp(suffix, caseInsensitive) {
return new RegExp(
String(suffix).replace(/[$%()*+.?\["]{|}]/g, "\\$&") + "$",
caseInsensitive ? "i" : "");
}
och sedan kan du använda det så här
makeSuffixRegExp("a[complicated]*suffix*").test(str)
Svar #3
- Tyvärr inte.
if( "mystring#".substr(-1) === "#" ) {}
Svar #4
Kom igen, detta är den korrekta endsWith-implementeringen:
String.prototype.endsWith = function (s) {
return this.length >= s.length && this.substr(this.length - s.length) == s;
}
att använda lastIndexOf skapar bara onödiga CPU-loopar om det inte finns någon matchning.
Svar #5
Denna version undviker att skapa en delsträng och använder inte reguljära uttryck (vissa regex-svar här fungerar; andra är trasiga):
String.prototype.endsWith = function(str)
{
var lastIndex = this.lastIndexOf(str);
return (lastIndex !== -1) && (lastIndex + str.length === this.length);
}
Om prestanda är viktigt för dig kan det vara värt att testa om lastIndexOf verkligen är snabbare än att skapa en delsträng eller inte. (Det kan mycket väl bero på vilken JS-motor du använder...) Det kan mycket väl vara snabbare i matchningsfallet och när strängen är liten - men när strängen är enorm måste den titta igenom hela även om vi egentligen inte bryr oss :(
För att kontrollera ett enda tecken, hitta längden och sedan använda charAt är förmodligen det bästa sättet.
Svar #6
Såg inte tillvägagångssättet med slice-metoden. Så jag lämnar det här:
function endsWith(str, suffix) {
return str.slice(-suffix.length) === suffix
}
Svar #7
Från developer.mozilla.org String.prototype.endsWith()
Sammanfattning
Metoden endsWith() avgör om en sträng slutar med tecknen från en annan sträng och returnerar true eller false beroende på vad som är lämpligt.
Syntax
str.endsWith(searchString [, position]);
Parametrar
searchString : Tecknen som ska sökas efter i slutet av denna sträng.
position : Sök inom denna sträng som om denna sträng endast vore så lång; standardvärdet är denna strängs faktiska längd, begränsad inom intervallet som fastställts av denna strängs längd.
Beskrivning
Denna metod låter dig avgöra om en sträng slutar med en annan sträng eller inte.
Exempel
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
Specifikationer
ECMAScript-språkspecifikation 6:e upplagan (ECMA-262)
Webbläsarkompatibilitet
Svar #8
return this.lastIndexOf(str) + str.length == this.length;
fungerar inte i det fall där den ursprungliga strängens längd är en mindre än söksträngens längd och söksträngen inte hittas:
lastIndexOf returnerar -1, sedan lägger du till längden på söksträngen och du får kvar den ursprungliga strängens längd.
En möjlig lösning är
return this.length >= str.length && this.lastIndexOf(str) + str.length == this.length
Svar #9
if( ("mystring#").substr(-1,1) == '#' )
-- Eller --
if( ("mystring#").match(/#$/) )
