Como verificar se uma string “StartsWith” é outra string?

Como eu iria escrever o equivalente de C # String.StartsWith em JavaScript?

 var haystack = 'hello world'; var needle = 'he'; //haystack.startsWith(needle) == true 

Nota: Esta é uma questão antiga e, como apontado nos comentários, o ECMAScript 2015 (ES6) introduziu o método .startsWith . No entanto, no momento em que escrevo esta atualização (2015), o suporte ao navegador está longe de estar completo .

   

Você pode usar o método String.prototype.startsWith() ECMAScript 6, mas ainda não é suportado em todos os navegadores . Você vai querer usar um shim / polyfill para adicioná-lo em navegadores que não o suportam. Criar uma implementação que esteja em conformidade com todos os detalhes descritos na especificação é um pouco complicado, e a versão definida nesta resposta não funcionará; Se você quiser um shim fiel, use:

  • Matthias Bynens’s String.prototype.startsWith shim ou
  • O es6-shim , que grava o máximo possível da especificação do ES6, incluindo String.prototype.startsWith .

Uma vez que você tenha shimmed o método (ou se você está apenas suportando navegadores e mecanismos de JavaScript que já o possuem), você pode usá-lo da seguinte maneira:

 "Hello World!".startsWith("He"); // true var haystack = "Hello world"; var prefix = 'orl'; haystack.startsWith(prefix); // false 

Outra alternativa com .lastIndexOf :

 haystack.lastIndexOf(needle, 0) === 0 

Isto olha para trás através do haystack para uma ocorrência de needle partir do índice 0 do haystack . Em outras palavras, ele só verifica se o haystack começa com a needle .

Em princípio, isso deve ter vantagens de desempenho em relação a outras abordagens:

  • Não procura o haystack inteiro.
  • Não cria uma nova cadeia temporária e, em seguida, descarta-a imediatamente.
 data.substring(0, input.length) === input 

Sem uma function auxiliar, apenas usando o método .test do regex:

 /^He/.test('Hello world') 

Para fazer isso com uma string dinâmica em vez de uma string codificada (supondo que a string não contenha nenhum caractere de controle regexp):

 new RegExp('^' + needle).test(haystack) 

Você deve verificar se há uma function RegExp.escape em JavaScript? se existe a possibilidade de que caracteres de controle de expressão regular apareçam na string.

Eu só queria adicionar minha opinião sobre isso.

Eu acho que podemos apenas usar assim:

 var haystack = 'hello world'; var needle = 'he'; if (haystack.indexOf(needle) == 0) { // Code if string starts with this substring } 

Melhor solução:

 function startsWith(str, word) { return str.lastIndexOf(word, 0) === 0; } startsWith("aaa", "a") true startsWith("aaa", "ab") false startsWith("abc", "abc") true startsWith("abc", "c") false startsWith("abc", "a") true startsWith("abc", "ba") false startsWith("abc", "ab") true 

E aqui está termina. Se você precisar disso também:

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

Para aqueles que preferem prototipá-lo em String:

 String.prototype.startsWith || (String.prototype.startsWith = function(word) { return this.lastIndexOf(word, 0) === 0; }); String.prototype.endsWith || (String.prototype.endsWith = function(word) { return this.indexOf(word, this.length - word.length) !== -1; }); 

Uso:

 "abc".startsWith("ab") true "c".ensdWith("c") true 

Aqui está uma pequena melhoria na solução do CMS:

 if(!String.prototype.startsWith){ String.prototype.startsWith = function (str) { return !this.indexOf(str); } } "Hello World!".startsWith("He"); // true var data = "Hello world"; var input = 'He'; data.startsWith(input); // true 

Verificar se a function já existe no caso de um navegador futuro implementá-la no código nativo ou se ela for implementada por outra biblioteca. Por exemplo, a Biblioteca de protótipos implementa essa function já.

Usando ! é um pouco mais rápido e mais conciso do que === 0 embora não seja tão legível.

Verifique também o underscore.string.js . Ele vem com startsWith methods úteis de teste e manipulação de strings, incluindo um método startsWith . Dos docs:

startsWith _.startsWith(string, starts)

Este método verifica se a string começa com o starts .

 _("image.gif").startsWith("image") => true 

Recentemente me fiz a mesma pergunta.
Existem várias soluções possíveis, aqui estão 3 válidas:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0 (adicionado depois de ver a resposta de Mark Byers)
  • usando um loop:

     function startsWith(s,starter) { for (var i = 0,cur_c; i < starter.length; i++) { cur_c = starter[i]; if (s[i] !== starter[i]) { return false; } } return true; } 

Eu não encontrei a última solução que faz uso de um loop.
Surpreendentemente, esta solução supera os primeiros 3 por uma margem significativa.
Aqui está o teste jsperf que realizei para chegar a essa conclusão: http://jsperf.com/startswith2/2

Paz

ps: ecmascript 6 (harmonia) introduz um método native startsWith para strings.
Basta pensar quanto tempo teria sido economizado se eles tivessem pensado em include esse método tão necessário na própria versão inicial.

Atualizar

Como Steve apontou (o primeiro comentário sobre esta resposta), a function customizada acima irá lançar um erro se o prefixo dado for menor que a string inteira. Ele corrigiu isso e adicionou uma otimização de loop que pode ser visualizada em http://jsperf.com/startswith2/4 .

Note que há duas otimizações de loop que Steve incluiu, o primeiro dos dois mostrou melhor desempenho, então eu vou postar esse código abaixo:

 function startsWith2(str, prefix) { if (str.length < prefix.length) return false; for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i) continue; return i < 0; } 

Como isso é tão popular, acho que vale a pena ressaltar que há uma implementação para esse método no ECMA 6 e, em preparação para isso, deve-se usar o polyfill “oficial” para evitar problemas e rasgos futuros.

Felizmente, os especialistas da Mozilla nos fornecem um:

https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith

 if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { position = position || 0; return this.indexOf(searchString, position) === position; }; } 

Observe que isso tem a vantagem de ser ignorado na transição para o ECMA 6.

A solução com melhor desempenho é parar de usar as chamadas da biblioteca e apenas reconhecer que você está trabalhando com duas matrizes. Uma implementação manual é curta e também mais rápida do que qualquer outra solução que vi aqui.

 function startsWith2(str, prefix) { if (str.length < prefix.length) return false; for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i) continue; return i < 0; } 

Para comparações de desempenho (sucesso e fracasso), consulte http://jsperf.com/startswith2/4 . (Certifique-se de verificar versões posteriores que possam ter superado as minhas.)

Acabei de aprender sobre essa biblioteca de strings:

http://stringjs.com/

Inclua o arquivo js e, em seguida, use a variável S assim:

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

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

 npm install string 

Então, exigindo-o como a variável S :

 var S = require('string'); 

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

 var str = 'hol'; var data = 'hola mundo'; if (data.length >= str.length && data.substring(0, str.length) == str) return true; else return false; 

Com base nas respostas aqui, esta é a versão que estou usando agora, pois parece dar o melhor desempenho com base no teste JSPerf (e é funcionalmente completo, tanto quanto eu posso dizer).

 if(typeof String.prototype.startsWith != 'function'){ String.prototype.startsWith = function(str){ if(str == null) return false; var i = str.length; if(this.length < i) return false; for(--i; (i >= 0) && (this[i] === str[i]); --i) continue; return i < 0; } } 

Isto foi baseado em startsWith2 daqui: http://jsperf.com/startswith2/6 . Eu adicionei um pequeno ajuste para uma pequena melhoria de desempenho, e desde então também adicionei uma verificação para a seqüência de comparação sendo nula ou indefinida, e converti-a para adicionar ao protótipo String usando a técnica na resposta do CMS.

Note que esta implementação não suporta o parâmetro "position" que é mencionado nesta página da Mozilla Developer Network , mas isso não parece fazer parte da proposta do ECMAScript.

Eu estava procurando por desempenho, então eu corri as funções através do jsperf. Eu testei as funções em relação a strings de assunto e pesquisa de vários tamanhos e parece que todos os methods exibem desempenho diferente de inputs diferentes; o padrão geral é que o desempenho diminui à medida que o comprimento da cadeia de pesquisa aumenta.

O vencedor geral acaba sendo o método substr(ing) .

https://jsperf.com/javascript-string-startswith

Se você está trabalhando com startsWith() e endsWith() então você deve ter cuidado com os espaços endsWith() . Aqui está um exemplo completo:

 var str1 = " Your String Value Here.!! "; // Starts & ends with spaces if (str1.startsWith("Your")) { } // returns FALSE due to the leading spaces… if (str1.endsWith("Here.!!")) { } // returns FALSE due to trailing spaces… var str2 = str1.trim(); // Removes all spaces (and other white-space) from start and end of `str1`. if (str2.startsWith("Your")) { } // returns TRUE if (str2.endsWith("Here.!!")) { } // returns TRUE 

Você também pode retornar todos os membros de uma matriz que começam com uma string criando seu próprio protótipo / extensão para o protótipo da matriz, também conhecido como

 Array.prototype.mySearch = function (target) { if (typeof String.prototype.startsWith != 'function') { String.prototype.startsWith = function (str){ return this.slice(0, str.length) == str; }; } var retValues = []; for (var i = 0; i < this.length; i++) { if (this[i].startsWith(target)) { retValues.push(this[i]); } } return retValues; }; 

E para usá-lo:

 var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster']; var myResult = myArray.mySearch('Hel'); // result -> Hello, Helium