Как я могу проверить, заканчивается ли строка определенным символом в JavaScript?
Пример: у меня есть строка
var str = "mystring#";
Я хочу знать, заканчивается ли эта строка на #. Как я могу это проверить?
Есть ли в JavaScript метод endsWith()?
Одно из моих решений - взять длину строки, получить последний символ и проверить его.
Это лучший способ или есть другой?
Вот Полностью совместимый со спецификацией полифилл для ES6 String.prototype.endsWith.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


if ( "mystring#".substr(-1) === "#" ) {}@Anthony, ммм ... так что используйте .Length-1, в чем проблема? if (mystring.substr (mystring.length-1) === "#") {} отлично работает в IE.
@ BrainSlugs83 - в этом и проблема: синтаксис '.length-1' работает в IE, а синтаксис '-1' - нет. Об этом нужно помнить, так что +1 Энтони за подсказку.
Не могли бы вы использовать slice()? У меня это работает в моем быстром тесте IE7.
уродливый IE. когда он умрет?
if ( ("mystring#").substr(-1,1) == '#' )
-- Или же --
if ( ("mystring#").match(/#$/) )
все они - очень полезные примеры. Добавление String.prototype.endsWith = function(str) поможет нам просто вызвать метод, чтобы проверить, заканчивается ли им наша строка или нет, ну, regexp также сделает это.
Я нашел лучшее решение, чем мое. Спасибо всем.
Эта версия избегает создания подстроки и не использует регулярные выражения (некоторые ответы с регулярными выражениями здесь будут работать; другие не работают):
String.prototype.endsWith = function(str)
{
var lastIndex = this.lastIndexOf(str);
return (lastIndex !== -1) && (lastIndex + str.length === this.length);
}
Если для вас важна производительность, стоит проверить, действительно ли lastIndexOf работает быстрее, чем создание подстроки. (Это может зависеть от используемого вами JS-движка ...) Это может быть быстрее в случае сопоставления и когда строка мала, но когда строка огромна, ей нужно просмотреть все это даже хотя нам все равно :(
Для проверки одного символа, вероятно, лучшим способом будет определение длины и последующее использование charAt.
Если this.lastIndexOf () возвращает -1, вы можете попасть в случаи, когда он возвращает true, в зависимости от this.length и str.length. Добавьте тест, который lastIndexOf ()! = -1.
Почему не работает метод регулярного выражения?
@izb: ответы, которые старше моих, которые пытаются использовать str+"$" в качестве регулярного выражения, не работают, поскольку они могут быть недействительными регулярными выражениями.
return this.lastIndexOf(str) + str.length == this.length;
не работает в случае, если исходная длина строки на единицу меньше длины строки поиска, а строка поиска не найдена:
lastIndexOf возвращает -1, затем вы добавляете длину строки поиска, и у вас остается исходная длина строки.
Возможное исправление
return this.length >= str.length && this.lastIndexOf(str) + str.length == this.length
Вы получили значок «Нашли ошибку в ответе Джона Скита». См. Подробности в вашем профиле.
/#$/.test(str)
будет работать во всех браузерах, не требует исправления обезьяны String и не требует сканирования всей строки, как это делает lastIndexOf, когда совпадений нет.
Если вы хотите сопоставить постоянную строку, которая может содержать специальные символы регулярного выражения, например '$', вы можете использовать следующее:
function makeSuffixRegExp(suffix, caseInsensitive) {
return new RegExp(
String(suffix).replace(/[$%()*+.?\[\\\]{|}]/g, "\\$&") + "$",
caseInsensitive ? "i" : "");
}
а затем вы можете использовать это так
makeSuffixRegExp("a[complicated]*suffix*").test(str)
Это удобно и просто, если вы проверяете постоянную подстроку.
lastIndexOf просматривает всю строку? Я думал, что это будет поиск от конца до начала.
а какое объяснение? Если я хочу найти шаблон «asdf», могу ли я использовать /asdf$/.test(str)?
@TomBrito, lastIndexOf сканирует всю строку, только если не находит совпадений или находит совпадение в начале. Если в конце есть совпадение, оно работает пропорционально длине суффикса. Да, /asdf$/.test(str) верен, когда str заканчивается на "asdf".
@TomBrito, отредактировано, чтобы прояснить, что делает lastIndexOf. Спасибо что подметил это.
Спасибо, но я до сих пор не понимаю, что означают косые черты в javascript. У этого есть имя?
@Tom Brito, это литерал регулярного выражения. Синтаксис заимствован из Perl. См. developer.mozilla.org/en/Core_JavaScript_1.5_Guide/… или ненужный уровень детализации в разделе 7.8.5 спецификации языка EcmaScript.
@Mike Samuel: Хороший ответ, но я все еще задаюсь вопросом, действительно ли развертывание нового механизма регулярных выражений более производительно, чем сканирование строки, или, если это было сделано правильно, просто вызывая подстроку (тем более, что ваш вызов makeSuffixRegExp делает очень сложная замена, которая, в конце концов, потребует пару полных сканирований строк и немного логики самим механизмом регулярных выражений ...)
@Tom Brito: Regex - действительно отличный инструмент, который нужно иметь в своем арсенале инструментов, когда он вам нужен, просто помните, что не все проблемы - это гвозди. Regular-Expressions.info - отличное место, чтобы узнать больше.
@ BrainSlugs83, я согласен по поводу ногтей. С точки зрения производительности на некоторых старых интерпретаторах (при условии, что регулярное выражение кэшировано) тест представлял собой единственный вызов машинного кода, в то время как решения для подстрок, как правило, требовали нескольких медленных инструкций интерпретатора и дорогостоящих экземпляров объектов. С современными переводчиками дело обстоит иначе. Очевидно, единственный способ узнать это - провести сравнительный анализ.
+1 за кроссбраузерность. Протестировано в Chrome 28.0.1500.72 m, Firefox 22.0 и IE9.
Круто, я об этом не подумал. Так просто и без обезьяньих исправлений. Спасибо!
Использование регулярного выражения медленнее, чем просто проверка конца строки, даже на быстрых языках.
Вы можете использовать что-то вроде: /kmz$/i.test(stringToTest) для проверки без учета регистра
Да ладно, это правильная реализация endsWith:
String.prototype.endsWith = function (s) {
return this.length >= s.length && this.substr(this.length - s.length) == s;
}
использование lastIndexOf просто создает ненужные циклы ЦП, если совпадений нет.
Согласовано. Я действительно чувствую, что это наиболее производительное решение из предлагаемых, так как оно имеет ранние прерывания / проверку работоспособности, оно короткое и лаконичное, оно элегантно (перегрузка прототипа строки), а подстрока кажется гораздо меньшим попаданием в ресурс, чем раскрутка механизма регулярных выражений.
Также нравится это решение. Неправильно написано просто название функции. Должно быть "endWith".
@ BrainSlugs83 Прошло пару лет, но теперь этот метод не быстрее, чем метод indexOf, упомянутый выше чакритом, а в Safari он на 30% медленнее! Вот тест jsPerf для случая сбоя примерно для 50-символьной строки: jsperf.com/endswithcomparison
Вероятно, следует использовать ===.
ОБНОВЛЕНИЕ (24 ноября 2015 г.):
Этот ответ изначально был опубликован в 2010 году (ШЕСТЬ лет назад), поэтому обратите внимание на эти проницательные комментарии:
Update for Googlers - Looks like ECMA6 adds this function. The MDN article also shows a polyfill. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
Creating substrings isn't expensive on modern browsers; it may well have been in 2010 when this answer was posted. These days, the simple
this.substr(-suffix.length) === suffixapproach is fastest on Chrome, the same on IE11 as indexOf, and only 4% slower (fergetaboutit territory) on Firefox: jsperf.com/endswith-stackoverflow/14 And faster across the board when the result is false: jsperf.com/endswith-stackoverflow-when-falseOf course, with ES6 adding endsWith, the point is moot. :-)
ОРИГИНАЛЬНЫЙ ОТВЕТ:
Я знаю, что это годовой вопрос ... но он мне тоже нужен, и мне нужно, чтобы он работал в кросс-браузере, поэтому ... объединение всех ответов и комментариев и немного его упростим:
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
indexOf для самых быстрых результатовindexOf, чтобы пропустить впередКроме того, если вам не нравится вставлять что-то в прототипы собственных структур данных, вот отдельная версия:
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
Обновлено: Как отметил @hamish в комментариях, если вы хотите ошибиться и проверить, была ли уже предоставлена реализация, вы можете просто добавить проверку typeof следующим образом:
if (typeof String.prototype.endsWith !== 'function') {
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
}
Обновление для гуглеров - похоже, что ECMA6 добавляет эту функцию. В статье MDN также показан полифилл. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Какая моя строка содержит несколько суффиксов?
@ lukas.pukenis он пропускает до конца и проверяет только один экземпляр суффикса в самом конце. не имеет значения, появляется ли строка поиска в другом месте.
@chakrit спасибо за разъяснения. Ваш код действительно прекрасен
Добавление проверки для ситуации, когда аргумент "суффикс" не определен ": if (typeof String.prototype.endsWith! == 'function') {String.prototype.endsWith = function (суффикс) {вернуть this.indexOf (суффикс , this.length - ((суффикс && суффикс.length) || 0))! == -1;};}
Какие сложности с регулярным выражением вы упомянули?
@AlexanderN: Конечно, endsWithSlow в что jsPerf делает что-то другое, чем другие: он нечувствителен к регистру (и не будет работать, если проверяемое значение содержит какие-либо символы со специальным значением в регулярных выражениях). Только вызовы toLowerCase делают этот тест недействительным по сравнению с другими.
Создание подстрок не требует больших затрат в современных браузерах; это могло быть в 2010 году, когда был опубликован этот ответ. В наши дни простой подход this.substr(-suffix.length) === suffix является самым быстрым в Chrome, таким же в IE11, как и indexOf, и только на 4% медленнее (территория вокруг него) в Firefox: jsperf.com/endswith-stackoverflow/14 И быстрее по всем направлениям, когда результат ложный: jsperf.com/endswith-stackoverflow-when-false Конечно, с добавлением ES6 endsWith, вопрос спорный. :-)
@BenjaminDobell, вы действительно читали код? второй параметр заставляет функцию пропускать вперед и проверять только единственное возможное место: length - suffix.length
@chakrit Ну да, видимо, не очень досконально. Я приношу извинения!
@BenjaminDobell, не беспокойтесь :)
Собственный метод endWith (), добавленный в es2015, также работает в Chrome быстрее, чем все другие методы. jsperf.com/endswith-stackoverflow/16
@IcedDante - "Какие сложности с регулярным выражением вы упомянули?" Я предполагаю, что проблема с RegEx заключается в том, что необходимо позаботиться о том, чтобы любые «специальные» символы в поисковом «шаблоне» были правильно экранированы. Это может быть сложно, если «Шаблон» получен из произвольных данных, особенно для тех, кто не разбирается в RegEx. Но в остальном решение RegEx должно работать нормально.
Если вы хотите реализовать String.prototype.endsWith, если он не существует, вам действительно нужно убедиться, что он совместим с собственной реализацией! Здесь вы опускаете необязательный аргумент «позиция», который может нарушить любой сторонний код! Пожалуйста, используйте полифил, разработанный MDN.
Разве это не должно быть просто ===0, а не !==-1, поскольку это единственное положение, в котором он может находиться?
Или как насчет !str.indexOf(...) :)
Если вы следуете подходу this.substr(-suffix.length) === suffix, вы можете использовать this.substr(-suffix.length, suffix.length) === suffix для получения поведения endswith('abc', '') = true.
Работает нормально и для IE. Спасибо :)
function check(str)
{
var lastIndex = str.lastIndexOf('/');
return (lastIndex != -1) && (lastIndex == (str.length - 1));
}
если вы не хотите использовать lasIndexOf или substr, то почему бы просто не посмотреть на строку в ее естественном состоянии (т.е. массив)
String.prototype.endsWith = function(suffix) {
if (this[this.length - 1] == suffix) return true;
return false;
}
или как отдельная функция
function strEndsWith(str,suffix) {
if (str[str.length - 1] == suffix) return true;
return false;
}
Способом будущего подтверждения и / или предотвращения перезаписи существующего прототипа будет тестовая проверка, чтобы увидеть, был ли он уже добавлен к прототипу String. Вот мой взгляд на версию с высоким рейтингом без регулярных выражений.
if (typeof String.endsWith !== 'function') {
String.prototype.endsWith = function (suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
}
Лучше всего использовать if (!String.prototype.hasOwnProperty("endsWith")). С typeof «MooTools и некоторые другие библиотеки AJAX облажаются», согласно «Крокфорд по JavaScript - Уровень 7: ECMAScript 5: Новые части» в 15:50 мин.
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)/));
String.prototype.endsWith = function(str)
{return (this.match(str+"$")==str)}
String.prototype.startsWith = function(str)
{return (this.match("^"+str)==str)}
надеюсь, это поможет
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…
традиционный способ
function strStartsWith(str, prefix) {
return str.indexOf(prefix) === 0;
}
function strEndsWith(str, suffix) {
return str.match(suffix+"$")==suffix;
}
Вы должны экранировать свою строку для escape-последовательностей регулярных выражений
Регулярные выражения работают медленно даже в быстрых языках. Просто проверьте конец строки.
Не знаю как вы, но:
var s = "mystring#";
s.length >= 1 && s[s.length - 1] == '#'; // will do the thing!
Почему именно регулярные выражения? Зачем возиться с прототипом? substr? да брось...
Потому что иногда лучше, когда это W.E.T.
Это основано на принятом ответе @ charkit, позволяющем передавать либо массив строк, либо строку в качестве аргумента.
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.info(value, (this.indexOf(value, this.length - value.length) !== -1));
return this.indexOf(value, this.length - value.length) !== -1;
}, this);
}
};
}
Для этого требуется символ подчеркивания, но его, вероятно, можно изменить, чтобы удалить зависимость подчеркивания.
Это плохое решение, скорее, если вы уже используете подчеркивание, вам следует добавить этот epeli.github.io/underscore.string в свои зависимости и использовать их реализацию: _.str.endsWith
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
;
};
}
Выгоды:
Не используйте регулярные выражения. Они медленные даже на быстрых языках. Просто напишите функцию, которая проверяет конец строки. В этой библиотеке есть хорошие примеры: Groundjs / util.js. Будьте осторожны, добавляя функцию в String.prototype. В этом коде есть хорошие примеры того, как это сделать: Groundjs / prototype.js В общем, это хорошая библиотека языкового уровня: Groundjs Вы также можете взглянуть на lodash
С сайта developer.mozilla.org String.prototype.endsWith ()
Метод endsWith() определяет, заканчивается ли строка символами другой строки, возвращая, при необходимости, истину или ложь.
str.endsWith(searchString [, position]);
searchString: Символы, которые нужно искать в конце этой строки.
позиция: Ищите в этой строке, как если бы эта строка была только этой длины; по умолчанию используется фактическая длина этой строки, ограниченная диапазоном, установленным длиной этой строки.
Этот метод позволяет определить, заканчивается ли строка другой строкой.
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
Спецификация языка ECMAScript, 6-е издание (ECMA-262)
Я только что узнал об этой строковой библиотеке:
Включите файл js, а затем используйте переменную S следующим образом:
S('hi there').endsWith('hi there')
Его также можно использовать в NodeJS, установив его:
npm install string
Затем потребуйте его как переменную S:
var S = require('string');
На веб-странице также есть ссылки на альтернативные строковые библиотеки, если эта вам не нравится.
function strEndsWith(str,suffix) {
var reguex= new RegExp(suffix+'$');
if (str.match(reguex)!=null)
return true;
return false;
}
Лучше, если вы объясните Почему, что ваш код решает проблему. См. Руководство Как ответить.
аргумент суффикса должен быть просканирован на предмет наличия регулярных выражений, которые необходимо экранировать. использование indexOf или lastIndexOf кажется лучшим вариантом.
Это не сработает, если суффикс содержит любой из этих символов:. * +? ^ =!: $ {} () [] / \
Для coffeescript
String::endsWith = (suffix) ->
-1 != @indexOf suffix, @length - suffix.length
Так много всего для такой маленькой проблемы, просто используйте это регулярное выражение
var str = "mystring#";
var regex = /^.*#$/
if (regex.test(str)){
//if it has a trailing '#'
}Принятый ответ @chakrit - отличный способ сделать это самостоятельно. Однако, если вы ищете пакетное решение, я рекомендую взглянуть на underscore.string, как указал @mlunoe. Используя underscore.string, код будет таким:
function endsWithHash(str) {
return _.str.endsWith(str, '#');
}
На этот вопрос ушло много лет. Позвольте мне добавить важное обновление для пользователей, которые хотят использовать ответ, получивший наибольшее количество голосов.
Функции endWith уже добавлены в JavaScript как часть ECMAScript 6 (экспериментальная технология)
Ссылка здесь: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
Следовательно, настоятельно рекомендуется добавить проверку наличия собственной реализации, как указано в ответе.
Еще одна быстрая альтернатива, которая сработала для меня, используя регулярное выражение:
// Would be equivalent to:
// "Hello World!".endsWith("World!")
"Hello World!".match("World!$") != null
Не увидел подхода с методом slice. Так что я просто оставлю это здесь:
function endsWith(str, suffix) {
return str.slice(-suffix.length) === suffix
}
Вы можете немного упростить его: return str.slice (-1) === suffix;
Это лучший ответ. Не уверен, почему он не набирает больше голосов.
Пост 7 лет назад, но я не смог понять несколько верхних постов, потому что они сложные. Итак, я написал собственное решение:
function strEndsWith(str, endwith)
{
var lastIndex = url.lastIndexOf(endsWith);
var result = false;
if (lastIndex > 0 && (lastIndex + "registerc".length) == url.length)
{
result = true;
}
return result;
}
После всех этих долгих ответов я нашел этот фрагмент кода простым и легким для понимания!
function end(str, target) {
return str.substr(-target.length) == target;
}
Это реализация endsWith:
String.prototype.endsWith = function (str) {
return (this.length >= str.length) && (this.substr(this.length - str.length) === str);
}
Это реализация endWith:
String.prototype.endsWith = function (str) {
return this.length >= str.length && this.substr(this.length - str.length) == str;
}
Это должен быть связанный вопрос: stackoverflow.com/questions/646628/javascript-startswith