Вопрос: Как проверить, содержит ли строка «StartsWith» другую строку?


Как бы я написал эквивалент C # String.StartsWithв JavaScript?

var haystack = 'hello world';
var needle = 'he';

//haystack.startsWith(needle) == true

Примечание. Это старый вопрос, и, как указано в комментариях, ECMAScript 2015 (ES6) представил .startsWithметод. Однако на момент написания этого обновления (2015 г.) поддержка браузера далека от завершения ,


1534


источник


Ответы:


Вы можете использовать ECMAScript 6 String.prototype.startsWith()метод, но это еще не поддерживается во всех браузерах , Вы захотите использовать прокладку / полиполк, чтобы добавить ее в браузеры, которые ее не поддерживают. Создание реализации, которая соответствует все детали, изложенные в спецификации немного сложнее, и версия, определенная в этом ответе, не будет делать; если вы хотите точную прокладку, используйте либо:

После того как вы настроили метод (или если вы только поддерживаете браузеры и движки JavaScript, которые уже есть), вы можете использовать его следующим образом:

"Hello World!".startsWith("He"); // true

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

1648



Другая альтернатива .lastIndexOf:

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

Это выглядит haystackдля возникновения needleначиная с индекса 0из haystack, Другими словами, он проверяет только haystackначинается с needle,

В принципе, это должно иметь преимущества производительности по сравнению с некоторыми другими подходами:

  • Он не ищет весь haystack,
  • Он не создает новую временную строку и сразу же отбрасывает ее.

1216



data.substring(0, input.length) === input

567



Without a helper function, just using regex's .test method:

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

To do this with a dynamic string rather than a hardcoded one (assuming that the string will not contain any regexp control characters):

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

You should check out Is there a RegExp.escape function in Javascript? if the possibility exists that regexp control characters appear in the string.


179



I just wanted to add my opinion about this.

I think we can just use like this:

var haystack = 'hello world';
var needle = 'he';

if (haystack.indexOf(needle) == 0) {
  // Code if string starts with this substring
}

50



Best solution:

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

And here is endsWith if you need that too:

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

For those that prefer to prototype it into 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;
});

Usage:

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

39



Here is a minor improvement to CMS's solution:

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

Checking whether the function already exists in case a future browser implements it in native code or if it is implemented by another library. For example, the Prototype Library implements this function already.

Using ! is slightly faster and more concise than === 0 though not as readable.


37



Also check out underscore.string.js. It comes with a bunch of useful string testing and manipulation methods, including a startsWith method. From the docs:

startsWith _.startsWith(string, starts)

This method checks whether string starts with starts.

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

21



I recently asked myself the same question.
There are multiple possible solutions, here are 3 valid ones:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0 (added after seeing Mark Byers's answer)
  • using a 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;
    }
    

I haven't come across the last solution which makes uses of a loop.
Surprisingly this solution outperforms the first 3 by a significant margin.
Here is the jsperf test I performed to reach this conclusion: http://jsperf.com/startswith2/2

Peace

ps: ecmascript 6 (harmony) introduces a native startsWith method for strings.
Just think how much time would have been saved if they had thought of including this much needed method in the initial version itself.

Update

As Steve pointed out (the first comment on this answer), the above custom function will throw an error if the given prefix is shorter than the whole string. He has fixed that and added a loop optimization which can be viewed at http://jsperf.com/startswith2/4.

Note that there are 2 loop optimizations which Steve included, the first of the two showed better performance, thus I will post that code below:

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

15