endsWith em JavaScript


1103

Como posso verificar se uma string termina com um caractere específico em JavaScript?

Exemplo: Eu tenho uma string

var str = "mystring#";

Quero saber se essa sequência está terminando com #. Como posso verificar?

  1. Existe um endsWith()método em JavaScript?

  2. Uma solução que tenho é pegar o comprimento da string e pegar o último caractere e verificar.

Essa é a melhor maneira ou existe outra maneira?


5
Isso tem que ser uma questão relacionada: stackoverflow.com/questions/646628/javascript-startswith
Hamish Grubijan

Respostas:


1764

ATUALIZAÇÃO (24 de novembro de 2015):

Esta resposta foi originalmente publicada no ano de 2010 (SIX anos atrás). Portanto, observe estes comentários perspicazes:


RESPOSTA ORIGINAL:

Sei que essa é uma pergunta de um ano ... mas eu também preciso disso e preciso que ela funcione em vários navegadores ... combinando a resposta e os comentários de todos e simplificando um pouco:

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
  • Não cria uma substring
  • Usa a indexOffunção nativa para obter resultados mais rápidos
  • Ignore comparações desnecessárias usando o segundo parâmetro de indexOfpara avançar
  • Funciona no Internet Explorer
  • Sem complicações no Regex

Além disso, se você não gosta de colocar coisas nos protótipos da estrutura de dados nativa, aqui está uma versão autônoma:

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

EDIT: Como observado por @hamish nos comentários, se você quiser errar do lado seguro e verificar se uma implementação já foi fornecida, basta adicionar uma typeofverificação da seguinte forma:

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

42
Atualização para googlers - parece que o ECMA6 adiciona esta função. O artigo MDN também mostra um polyfill. developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Shauna

2
@ lukas.pukenis pula para o final e verifica apenas uma instância do sufixo no final. não importa se a string de pesquisa aparece em outro lugar.
chakrit,

3
Adicionando uma verificação para a situação em que o argumento "sufixo" não está definido ": if (tipo de String.prototype.endsWith! == 'function') {String.prototype.endsWith = function (sufixo) {retorne this.indexOf (sufixo , this.length - ((sufixo && suffix.length) || 0))! == -1;};}
Mandeep

2
Quais são as complicações regex a que você se refere?
precisa saber é o seguinte

5
Criar substrings não é caro em navegadores modernos; pode ter sido em 2010 quando esta resposta foi publicada. Hoje em dia, a this.substr(-suffix.length) === suffixabordagem simples é mais rápida no Chrome, a mesma no IE11 indexOfe apenas 4% mais lenta (no território) no Firefox: jsperf.com/endswith-stackoverflow/14 E mais rápida quando o resultado é falso: jsperf .com / endswith-stackoverflow-when-false Naturalmente, com a adição do ES6 endsWith, o ponto é discutível. :-)
TJ Crowder

295
/#$/.test(str)

funcionará em todos os navegadores, não requer patch de macaco Stringe não exige a verificação de toda a string, como lastIndexOfocorre quando não há correspondência.

Se você deseja corresponder uma sequência constante que pode conter caracteres especiais de expressão regular, como '$', então, você pode usar o seguinte:

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

e então você pode usá-lo assim

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

10
Isso é agradável e simples se você estiver procurando por uma substring constante.
Warren Blanchet

1
lastIndexOf verifica toda a cadeia de caracteres? Eu pensei que iria procurar do fim ao começo.
19411 Tom Brito

3
@TomBrito, lastIndexOfvarre a sequência inteira apenas se não encontrar nenhuma correspondência ou encontrar uma correspondência no início. Se houver uma correspondência no final, ela funcionará proporcionalmente à duração do sufixo. Sim, /asdf$/.test(str)produz true quando strtermina com "asdf".
19611 Mike Samuel

3
@ Tom Brito, é uma expressão regular literal. A sintaxe é emprestada do Perl. Consulte developer.mozilla.org/en/Core_JavaScript_1.5_Guide/… ou para obter um nível de detalhe desnecessário, consulte a seção 7.8.5 da especificação da linguagem EcmaScript.
Mike Samuel

2
+1 para compatibilidade entre navegadores. Testado no Chrome 28.0.1500.72 m, Firefox 22.0 e IE9.
Adrien Seja

91
  1. Infelizmente não.
  2. if( "mystring#".substr(-1) === "#" ) {}

14
@ Anthony, hum ... então use .Length-1, qual é o problema? if (mystring.substr (mystring.length-1) === "#") {} funciona perfeitamente no IE.
BrainSlugs83

12
@ BrainSlugs83 - esse é exatamente o problema: a sintaxe '.length-1' funciona no IE, e a sintaxe '-1' não. É algo a ter em mente, então marque +1 com Anthony pela dica.
Avramov

2
Você não poderia usar slice()? Funciona para mim no meu teste rápido do IE7.
8284 alex

IE enlouquecido. quando vai morrer?
ahnbizcad

67

Vamos lá, esta é a endsWithimplementação correta :

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

usar lastIndexOfapenas cria loops desnecessários da CPU se não houver correspondência.


2
Acordado. Eu realmente sinto que esta é a solução com melhor desempenho oferecida, pois possui uma verificação antecipada de abortos / sanidade, é curta e concisa, é elegante (sobrecarregando o protótipo de cadeia de caracteres) e a substring parece muito menos um recurso atingido do que girar o mecanismo de regex.
BrainSlugs83

Também gosto desta solução. Apenas o nome da função está incorreto. Deve ser "endsWith".
xmedeko

3
@ BrainSlugs83 Já faz alguns anos, mas agora esse método não é mais rápido que o método 'indexOf' mencionado acima pelo chakrit e, no Safari, é 30% mais lento! Aqui está um teste jsPerf para o caso de falha em uma cadeia de 50 caracteres: jsperf.com/endswithcomparison
Brent Faust

4
Provavelmente deve usar ===embora.
Timmmm

56

Esta versão evita a criação de uma substring e não usa expressões regulares (algumas respostas regex aqui funcionarão; outras estão quebradas):

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

Se o desempenho é importante para você, vale a pena testar se lastIndexOf é realmente mais rápido do que criar uma substring ou não. (Pode depender do mecanismo JS que você está usando ...) Pode ser mais rápido no caso correspondente, e quando a string é pequena - mas quando a string é enorme, é necessário olhar para trás, mesmo embora realmente não nos importemos :(

Para verificar um único caractere, encontrar o comprimento e usá-lo charAté provavelmente o melhor caminho.


2
Se this.lastIndexOf () retornar -1, você poderá atingir os casos em que ele retorne true, dependendo de this.length e str.length. Adicione um teste que lastIndexOf ()! = -1.
ebruchez

1
Por que o método regex está quebrado?
izb

2
@izb: As respostas mais antigas que as minhas que tentam usar str+"$"como regex estão quebradas, pois podem não ser regex válidas.
Jon Skeet

26

Não vi a ligação com o slicemétodo Então, eu vou deixar aqui:

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

1
Você pode simplificar um pouco mais: retornar str.slice (-1) === sufixo;
Erik K.

2
Esta é a melhor resposta. Não sei por que não tem mais votos.
Nucleartide

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

não funciona no caso em que o comprimento da string original é um menor que o comprimento da string de pesquisa e a string de pesquisa não é encontrada:

lastIndexOf retorna -1, você adiciona o comprimento da string de pesquisa e fica com o comprimento da string original.

Uma possível correção é

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

30
Você ganhou o selo "Encontrou um erro em uma resposta de Jon Skeet". Veja seu perfil para obter detalhes.
bobince

17

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

Sumário

O endsWith()método determina se uma sequência termina com os caracteres de outra sequência, retornando verdadeiro ou falso, conforme apropriado.

Sintaxe

str.endsWith(searchString [, position]);

Parâmetros

  • searchString : os caracteres a serem pesquisados ​​no final dessa string.

  • position : pesquise nessa string como se ela tivesse apenas esse comprimento; assume como padrão o comprimento real dessa string, preso dentro do intervalo estabelecido pelo comprimento dessa string.

Descrição

Este método permite determinar se uma sequência termina ou não com outra.

Exemplos

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

Especificações

ECMAScript Language Specification 6ª Edição (ECMA-262)

Compatibilidade do navegador

Compatibilidade do navegador


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

- ou -

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

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

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

Eu espero que isso ajude

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…

a maneira tradicional

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

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

Você tem que escapar sua seqüência para seqüências de escape regex
Juan Mendes

1
Expressões regulares são lentas, mesmo em idiomas rápidos. Basta verificar o final de uma string.
Daniel Nuriyev

8

Não sei você, mas:

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

Por que expressões regulares? Por que mexer com o protótipo? substr? Vamos lá...


'cus às vezes é melhor quando está molhada
Martin Capodici

8

Apenas outra alternativa rápida que funcionou como um encanto para mim, usando o regex:

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


6

Acabei de aprender sobre esta biblioteca de strings:

http://stringjs.com/

Inclua o arquivo js e use a Svariável assim:

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

Também pode ser usado no NodeJS instalando-o:

npm install string

Em seguida, exigindo-o como a Svariável:

var S = require('string');

A página da web também possui links para bibliotecas de cadeias de caracteres alternativas, se esta não lhe agradar.


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

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

  return false;
}

1
É melhor se você explicar por que seu código resolve o problema. Veja o guia Como responder .
Brasofilo

o argumento do sufixo deve ser verificado quanto a expressões de expressões regulares que precisam ser escapadas. usar indexOf ou lastIndexOf parece ser uma opção melhor.
Vlad_tepesch

Não funcionará se o sufixo contiver algum destes caracteres:. * +? ^ =!: $ {} () [] / \
gtournie

4

Tantas coisas para um problema tão pequeno, basta usar esta Expressão Regular

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

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


4

Faz muitos anos para esta pergunta. Deixe-me adicionar uma atualização importante para os usuários que desejam usar a resposta do chakrit mais votada.

As funções 'endsWith' já foram adicionadas ao JavaScript como parte do ECMAScript 6 (tecnologia experimental)

Consulte aqui: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith

Portanto, é altamente recomendável adicionar a verificação da existência de implementação nativa, conforme mencionado na resposta.


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

2

Uma maneira de prova futura e / ou impedir a substituição do protótipo existente seria a verificação de teste para ver se ele já foi adicionado ao protótipo String. Aqui está a minha opinião sobre a versão não classificada como regex.

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

Usar if (!String.prototype.hasOwnProperty("endsWith"))é o melhor caminho. Com typeof, "MooTools e algumas das outras bibliotecas AJAX estragam você", de acordo com "Crockford on JavaScript - Nível 7: ECMAScript 5: The New Parts", às 15:50 min.
XP1

2

A resposta aceita do @ chakrit é uma maneira sólida de fazer você mesmo. Se, no entanto, você estiver procurando uma solução em pacote, recomendo dar uma olhada em underscore.string , como apontou @mlunoe. Usando underscore.string, o código seria:

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

1

se você não quiser usar lasIndexOf ou substr, por que não apenas olhar a string em seu estado natural (ou seja, uma matriz)

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

ou como uma função autônoma

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

Depois de todas essas longas respostas, achei esse código simples e fácil de entender!

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

1

Esta é a implementação de endsWith: String.prototype.endsWith = function (str) { return this.length >= str.length && this.substr(this.length - str.length) == str; }


1

Esta é a implementação de endsWith:

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

0

Isso se baseia na resposta aceita do @ charkit, permitindo que uma matriz de strings ou uma string seja passada como argumento.

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

Isso requer underscorejs - mas provavelmente pode ser ajustado para remover a dependência de sublinhado.


1
Esta é uma péssima solução; se você já estiver usando sublinhado, adicione este epeli.github.io/underscore.string às suas dependências e use a implementação delas:_.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
        ;
    };
}

Benefícios:

  • Esta versão não está apenas reutilizando o indexOf.
  • Maior desempenho em cordas longas. Aqui está um teste de velocidade http://jsperf.com/starts-ends-with/4
  • Totalmente compatível com a especificação ecmascript. Passa nos testes

0

Não use expressões regulares. Eles são lentos, mesmo em idiomas rápidos. Basta escrever uma função que verifique o final de uma string. Esta biblioteca tem exemplos agradáveis: groundjs / util.js . Cuidado ao adicionar uma função ao String.prototype. Este código tem bons exemplos de como fazê-lo: groundjs / prototype.js Em geral, esta é uma boa biblioteca em nível de idioma: groundjs Você também pode dar uma olhada no lodash


0

todos eles são exemplos muito úteis. AdicionandoString.prototype.endsWith = function(str) nos ajudará a simplesmente chamar o método para verificar se nossa string termina com ela ou não, bem, o regexp também fará isso.

Encontrei uma solução melhor que a minha. Obrigado a todos.


0

Para café

String::endsWith = (suffix) ->
  -1 != @indexOf suffix, @length - suffix.length
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.