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

вопрос создан в Sat, Sep 8, 2018 12:00 AM

Как мне написать эквивалент C # String.StartsWith в JavaScript? р>  

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

haystack.startsWith(needle) == true

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

    
1618
16 ответов                              16                         

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

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

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

var haystack = "Hello world";
var prefix = 'orl';
haystack.startsWith(prefix); // false
    
1721
2019-05-07 03: 56: 14Z
  1. JSPerf с собственным startsWith: jsperf. ком /JS-startwith-прототип /8
    2016-03-04 16: 13: 49Z
  2. @ gtournie, почему при запуске с одним из худших методов проверки, начинается ли строка со строки? (см. ваш комментарий здесь: stackoverflow.com/questions/646628/… ) вы более увлечены сравнением символов для каждого символа. я надеюсь, что компиляторы достаточно умны, чтобы НЕ генерировать строку для каждой строки [index], потому что, если вы просто напишите это: character = string [0], это БУДЕТ выделять объект, бесконечно МЕНЬШЕ эффективнее, чем использование startWith (startWith не будет выделять какую-либо память )
    2016-07-20 16: 32: 26Z
  3. @ MartijnScheffer: ответ был отредактирован много раз с тех пор, как я ответил, и теперь он совершенно другой (я удалил свой комментарий;). Я согласен с тем, что метод startWith в ECMAScript 6 - лучший способ сделать это.
    2016-07-20 18: 26: 32Z
  4. @ GrahamLaight, когда вы говорите, что поддерживается IE, предположительно вы имеете в виду Edge. developer.mozilla.org/en/docs/Web /JavaScript /Справочник /...
    2016-08-09 19: 03: 41Z
  5. @ Маркус, извиняюсь, если я ошибся - моя информация получена от: w3schools.com/jsref/jsref_startswith.asp
    2016-08-10 10: 06: 03Z

Еще одна альтернатива - .lastIndexOf :  

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

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

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

  • Он не выполняет поиск по всему haystack.
  • Он не создает новую временную строку, а затем сразу же удаляет ее.
1256
2015-11-05 00: 30: 07Z
  1. Не уверен, о каком случае @ rfcoder89 идет речь - jsfiddle.net/jkzjw3w2/1
    2016-05-20 11: 15: 18Z
  2. @ rfcoder89 Обратите внимание, что второй параметр lastIndexOf: "aba".lastIndexOf ("a") равен 2, как вы указали, но "aba".lastIndexOf ("a", 0) равен 0, что правильно
    2016-05-20 14: 37: 01Z
  3. Большое спасибо. String.startsWith не работает в Android lollipop WebView, но этот фрагмент lastIndexOf работает !!!
    2016-12-06 23: 22: 17Z
  4. с lastIndexOf строка ищется с конца до начала, поэтому она ищет всю строку: поэтому ее неэффективность возрастает для очень длинных строк поиск в.
    2017-04-08 00: 18: 02Z
  5. @ willywonka Нет, это не так, если у вас 0 startIndex, поиск производится по 0 pos, и это единственная проверка. Вся строка ищется, только если fromIndex > = str.length.
    2017-05-19 08: 27: 42Z
 
data.substring(0, input.length) === input
    
584
2011-06-06 14: 24: 26Z
  1. @ ANeves Я подозреваю, что это сильно зависит от браузера и используемых данных. См. Ответ Бена Уивера для реальных измерений. В браузере, в котором я сейчас работаю (Chrome 12.0.742 для Windows), подстрока выигрывает для успеха и готовит регулярные выражения для неудачи.
    2011-07-14 17: 11: 24Z
  2. @ cobbal Возможно. Но .lastIndexOf(input, 0) сравнивает первые N символов, тогда как .substring(0, input.length) === input считает N, подставляет данные в длину N, а затем сравнивает эти N символов. Если нет оптимизации кода, эта вторая версия не может быть быстрее, чем другая. Не поймите меня неправильно, я никогда не найду ничего лучше, чем вы предлагаете. :)
    2011-07-18 09: 19: 41Z
  3. @ ANeves Но .lastIndexOf в длинной строке, которая будет возвращать false, будет выполнять итерацию по всей строке (O (N)), тогда как в случае .substring выполняется итерация над потенциально гораздо меньшей строкой. Если вы ожидаете большинства успехов или только небольших входных данных, .lastIndexOf, вероятно, быстрее, в противном случае .substring, вероятно, быстрее. .substring также рискует исключение, если входные данные длиннее проверяемой строки.
    2013-01-22 20: 18: 28Z
  4. @ ChrisMoschini, не забывайте, что решение Марка Байерса имеет lastIndexOf, начиная с индекса 0, а не с конца. Это поначалу меня тоже сбило с толку. Тем не менее, проверка того, с чего начинается строка, является настолько распространенной задачей, что JavaScript действительно должен иметь соответствующий API, а не все идиомы и альтернативы, которые вы видите на этой странице, какими бы умными они ни были.
    2013-01-29 20: 58: 05Z
  5. Я предпочитаю решение Коббала, а не Марка. Даже если метки быстрее и это впечатляющий трюк с использованием параметров, его очень трудно прочитать по сравнению с подстрокой.
    2015-02-13 23: 17: 00Z

Без вспомогательной функции, просто используйте reax .test метод:

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

Чтобы сделать это с динамической строкой, а не жестко закодированной (при условии, что строка не будет содержать управляющих символов регулярного выражения):

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

Вы должны проверить Есть ли функция RegExp.escape в Javascript ? если существует вероятность того, что в строке появятся управляющие символы регулярного выражения.

    
182
2017-05-23 12: 34: 50Z
  1. Чтобы сделать выражение чувствительным к регистру, используйте /^he/i
    2018-10-31 12: 50: 28Z

Лучшее решение:

 
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

А вот заканчивается с , если вам это тоже нужно:

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

Для тех, кто предпочитает создавать прототип в 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;
});

Использование:

 
"abc".startsWith("ab")
true
"c".ensdWith("c") 
true
    
55
2018-03-07 19: 25: 54Z
  1. Я думаю, что вы смешали lastIndexOf и indexOf в своих функциях - старты должны возвращать str.indexOf (word, 0) === 0;
    2017-01-12 14: 51: 47Z
  2. @ RichardMatheson. Проблема с использованием indexOf заключается в том, что если при запуске поиск не удастся найти, он продолжит поиск по всей строке, в результате чего lastIndexOf начинается с длины слова и возвращается к нулю. Понял?
    2017-01-27 08: 48: 06Z
  3. Ааа, да, теперь имеет смысл - я не обращал внимания на используемые вами индексы. Очень хороший трюк!
    2017-02-05 10: 54: 10Z

Я просто хотел добавить свое мнение по этому поводу.

Я думаю, что мы можем просто использовать это так:

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

if (haystack.indexOf(needle) == 0) {
  // Code if string starts with this substring
}
    
53
2016-02-12 14: 47: 19Z
  1. Ответ Марка Байерса был сравнен с @relfor для выполнения трех разных правильных подходов. Этот правильный подход не был одобрен, потому что он требует поиска по всей строке.
    2016-05-20 15: 24: 06Z
  2. @ maxpolk Я думаю, что indexOf прекратит поиск всей строки, когда найдет первый случай. Я проверил это.
    2016-05-21 03: 30: 26Z
  3. Если первое вхождение не найдено в самом начале, этот подход начинает становиться неэффективным, чем дольше он продолжает его искать, потенциально ища, пока не достигнет самого конца, вместо того, чтобы сдаться намного раньше. Поскольку существует потенциал неэффективности, он не является предпочтительным среди трех правильных подходов.
    2016-06-27 21: 04: 13Z
  4. @ Mr.D А если нет совпадения?
    2016-09-16 09: 58: 27Z
  5. @ momomo Затем добавьте код else.
    2016-09-16 10: 07: 33Z

Вот небольшое улучшение решения 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

Проверка, существует ли функция в случае, если будущий браузер реализует ее в собственном коде или если она будет реализована другой библиотекой. Например, библиотека прототипов уже реализует эту функцию.

Использование ! немного быстрее и более кратко, чем === 0, хотя и не так читабельно.

    
37
2015-11-18 18: 59: 19Z
  1. Это может стать проблемой: если уже реализованная реализация ведет себя не так, как у меня, это нарушит работу моего приложения.
    2011-07-12 09: 20: 20Z
  2. Здесь обсуждается проблема O (N) stackoverflow.com/questions/646628/javascript-startswith/…
    2013-01-30 07: 52: 32Z
  3. используя! там очень грязно
    2015-02-06 12: 52: 41Z
  4. - 1; добавление этого к String.prototype - плохая идея, потому что оно не подходит близко к соблюдению spec для String.prototype.startsWith. Любой код, который пытается использовать метод ES6, может потерпеть неудачу, если вы делаете это; он может хорошо посмотреть, если метод уже определен, увидеть, что он (плохо с вашей стороны), и не добавить в совместимую со спецификацией прокладку, что позже приведет к некорректному поведению.
    2015-11-05 23: 23: 28Z
  5. Это не хорошо.
    2016-09-16 09: 58: 54Z

Также ознакомьтесь с underscore.string.js . Он поставляется с набором полезных методов тестирования и манипуляции со строками, включая метод startsWith. Из документов:

  

начинается с _.startsWith(string, starts)

     

Этот метод проверяет, начинается ли string с starts.

 
_("image.gif").startsWith("image")
=> true
    
20
2014-04-19 11: 15: 42Z
  1. Мне нужно _.string.startsWith
    2014-07-25 21: 02: 50Z

Недавно я задал себе тот же вопрос.
Есть несколько возможных решений, вот 3 допустимых:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  •  s.lastIndexOf(starter, 0) === 0 (добавлено после просмотра ответа Марка Байерса )
  • используя цикл:

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

Я не сталкивался с последним решением, которое использует цикл.
Удивительно, но это решение значительно превосходит первые три.
Вот тест jsperf, который я провел, чтобы прийти к такому выводу: http://jsperf.com/startswith2/2 р>

Мир

ps: ecmascript 6 (гармония) представляет собственный метод startsWith для строк.
Подумайте, сколько времени было бы сэкономлено, если бы они решили включить этот столь необходимый метод в саму первоначальную версию.

Обновление

Как указал Стив (первый комментарий к этому ответу), указанная выше пользовательская функция выдаст ошибку, если указанный префикс короче всей строки. Он исправил это и добавил оптимизацию цикла, которую можно посмотреть на http://jsperf.com/startswith2/4 . р>

Обратите внимание, что есть 2 цикла оптимизации, которые включил Стив, первый из двух показал лучшую производительность, поэтому я опубликую этот код ниже:

 
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
2017-05-23 12: 10: 44Z
  1. Смотрите последнюю версию. Помимо ошибки в вышеупомянутой версии (она будет выдавать, если строка короче префикса), она также медленнее, чем более оптимизированная версия. См. jsperf.com/startswith2/4 и jsperf.com/js-startswith/35 .
    2014-07-15 01: 35: 34Z
  2. ^ Спасибо за указание на случай, когда строка короче префикса
    2014-10-29 18: 06: 46Z
  3. jsperf.com/startswith2/29 = &GT; StarsWith5 лаконичен и хорошо работает =)
    2015-11-17 07: 52: 43Z

Поскольку это настолько популярно, я думаю, что стоит отметить, что в ECMA 6 есть реализация этого метода, и при подготовке к нему следует использовать «официальный» полизаполнение, чтобы предотвратить будущие проблемы и разрывы. р>

К счастью, эксперты Mozilla предоставляют нам один:

https://developer.mozilla.org/де /Docs /Web /JavaScript /Справочник /Global_Objects /String /StartsWith

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

Пожалуйста, обратите внимание, что это имеет то преимущество, что изящно игнорируется при переходе на ECMA 6.

    
11
2016-02-27 06: 28: 04Z
  1. 2017-02-07 09: 21: 47Z

Лучшее решение - перестать использовать библиотечные вызовы и просто признать, что вы работаете с двумя массивами. Ручная реализация является одновременно короткой и более быстрой, чем любое другое решение, которое я видел здесь.

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

Сравнение производительности (успехов и неудач) см. в http://jsperf.com/startswith2/4. (Убедитесь, что вы проверили более поздние версии, которые могли превзойти мою.)

    
5
2015-11-05 01: 03: 55Z

Я только что узнал об этой строковой библиотеке:

http://stringjs.com/

Включите файл js, а затем используйте переменную S следующим образом:

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

Его также можно использовать в NodeJS, установив его:

 
npm install string

Затем требуется его как переменная S:

 
var S = require('string');

На веб-странице также есть ссылки на библиотеки альтернативных строк, если она вам не по вкусу.

    
2
2014-04-29 10: 22: 18Z
Элемент
 
var str = 'hol';
var data = 'hola mundo';
if (data.length >= str.length && data.substring(0, str.length) == str)
    return true;
else
    return false;
    
1
2012-10-21 05: 47: 40Z

Исходя из ответов, приведенных здесь, это версия, которую я сейчас использую, так как она, кажется, дает лучшую производительность на основе тестирования JSPerf (и насколько я могу судить функционально завершена).

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

Это было основано на стартах с помощью2 здесь: http://jsperf.com/startswith2/6 . Я добавил небольшой твик для незначительного улучшения производительности, а также добавил проверку на то, что строка сравнения имеет значение null или undefined, и преобразовал ее, чтобы добавить в прототип String, используя технику ответа CMS.

Обратите внимание, что эта реализация не поддерживает параметр "position", который упоминается в этом страницы Mozilla Developer Network , но в любом случае это не является частью предложения ECMAScript.

    
0
2014-09-24 15: 29: 26Z

Если вы работаете с startsWith() и endsWith(), вы должны быть осторожны с пробелами. Вот полный пример:

 
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
    
- 2
2018-01-01 10: 32: 41Z
  1. Это очень нестандартное поведение: строка «abc» НЕ начинается с «abc». Точнее говоря, ECMA 6 не предполагает какой-либо обрезки строк, поэтому пробельные символы должны точно совпадать, чтобы получить совпадение StartWith.
    2014-07-15 02: 01: 49Z
  2. Что ... как это отвечает на вопрос?
    2015-10-21 01: 05: 19Z
  3. @ DCShannon это не так. Это непонятная ерунда.
    2015-11-05 01: 19: 50Z
  4. @ SteveHollasch Я хотел узнать, кто ищет ту же проблему, с которой я столкнулся. Мы должны быть осторожны с пробелами при работе с функциями startsWith() и endsWith(). Ничего другого!
    2015-11-05 12: 27: 25Z

Вы также можете вернуть все члены массива, которые начинаются со строки, создав собственный прототип /расширение для прототипа массива, иначе

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

И использовать это:

 
var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster'];
var myResult = myArray.mySearch('Hel');
// result -> Hello, Helium
    
- 3
2013-07-19 21: 50: 02Z
источник размещен Вот