Заканчивается в JavaScript

Как я могу проверить, заканчивается ли строка определенным символом в JavaScript?

Пример: у меня есть строка

var str = "mystring#";

Я хочу знать, заканчивается ли эта строка #, Как я могу это проверить?

  1. Есть ли endsWith() метод в JavaScript?

  2. Одно из решений, которое у меня есть, - взять длину строки, получить последний символ и проверить его.

Это лучший способ или есть другой способ?

31 ответ

Решение

ОБНОВЛЕНИЕ (24 ноября 2015 г.):

Этот ответ первоначально был опубликован в 2010 году (шесть лет назад), поэтому, пожалуйста, примите к сведению эти проницательные комментарии:

  • Shauna - обновление для Googlers. Похоже, ECMA6 добавляет эту функцию. Статья MDN также показывает polyfill. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith

  • T.J. Crowder - Создание подстрок не дорого в современных браузерах; возможно, это было в 2010 году, когда был опубликован этот ответ. В наши дни простые this.substr(-suffix.length) === suffix самый быстрый подход в Chrome, такой же в IE11, как indexOf, и только на 4% медленнее (территория fergetaboutit) в Firefox: http://jsperf.com/endswith-stackru/14 И быстрее по всем направлениям, когда результат ложен: http://jsperf.com/endswith-stackru-when-false Конечно, с ES6 добавление заканчивается, суть в споре. :-)


ОРИГИНАЛЬНЫЙ ОТВЕТ:

Я знаю, что это годичный вопрос... но мне это тоже нужно, и мне нужно, чтобы он работал кросс-браузерно, так что... объединяя ответы и комментарии каждого и немного упрощая его:

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
  • Не создает подстроку
  • Использует родной indexOf функция для самых быстрых результатов
  • Пропустить ненужные сравнения, используя второй параметр indexOf пропустить вперед
  • Работает в Internet Explorer
  • НЕТ регулярных выражений

Также, если вам не нравится вставлять вещи в прототипы нативной структуры данных, вот отдельная версия:

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;
    };
}
/#$/.test(str)

будет работать во всех браузерах, не требует патчей для обезьян Stringи не требует сканирования всей строки как lastIndexOf делает, когда нет совпадений.

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

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

и тогда вы можете использовать это так

makeSuffixRegExp("a[complicated]*suffix*").test(str)
  1. К сожалению нет.
  2. if( "mystring#".substr(-1) === "#" ) {}

Да ладно, это правильно endsWith реализация:

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

с помощью lastIndexOf просто создает ненужные циклы процессора, если нет совпадения.

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

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

Если производительность важна для вас, стоит проверить lastIndexOf на самом деле быстрее, чем создание подстроки или нет. (Это может зависеть от используемого вами механизма JS...) В соответствующем случае он может быть быстрее, а когда строка небольшая - но когда строка огромная, нужно оглянуться назад, даже если хотя нам все равно:(

Для проверки одного символа, определения длины и последующего использования charAt это, наверное, лучший способ.

Не видел apporach с slice метод. Так что я просто оставлю это здесь:

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

От developer.mozilla.org String.prototype.endsWith ()

Резюме

endsWith() Метод определяет, заканчивается ли строка символами другой строки, возвращая true или false в зависимости от ситуации.

Синтаксис

str.endsWith(searchString [, position]);

параметры

  • searchString: символы для поиска в конце этой строки.

  • position: Искать в этой строке, как если бы эта строка была только этой длинной; по умолчанию - фактическая длина этой строки, ограниченная в диапазоне, установленном длиной этой строки.

Описание

Этот метод позволяет определить, заканчивается ли строка другой строкой.

Примеры

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)

Совместимость браузера

Совместимость браузера

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

не работает в случае, когда длина исходной строки на единицу меньше длины строки поиска и строка поиска не найдена:

lastIndexOf возвращает -1, затем вы добавляете длину строки поиска, и у вас остается длина исходной строки.

Возможное исправление

return this.length >= str.length && this.lastIndexOf(str) + str.length == this.length
if( ("mystring#").substr(-1,1) == '#' )

-- Или же --

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

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

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

Я не знаю о вас, но:

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

Почему регулярные выражения? Зачем возиться с прототипом? зиЬзЬг? да брось...

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

Если вы используете lodash:

_.endsWith('abc', 'c'); // true

Если вы не используете lodash, вы можете позаимствовать его источник.

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

http://stringjs.com/

Включите файл JS, а затем используйте S переменная, как это:

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

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

npm install string

Тогда требуя это как S переменная:

var S = require('string');

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

Так много вещей для такой маленькой проблемы, просто используйте это регулярное выражение

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

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

Прошло много лет на этот вопрос. Позвольте мне добавить важное обновление для пользователей, которые хотят использовать ответ наиболее часто встречающегося чакрита.

Функции'ndsWith'уже добавлены в JavaScript как часть ECMAScript 6 (экспериментальная технология)

См. Здесь: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith

Поэтому настоятельно рекомендуется добавить проверку на наличие нативной реализации, как указано в ответе.

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

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

  return false;
}

Принятый ответ @chakrit - это надежный способ сделать это самостоятельно. Однако, если вы ищете пакетное решение, я рекомендую взглянуть на http://epeli.github.io/underscore.string/, как указывал @mlunoe. Используя underscore.string, код будет:

function endsWithHash(str) {
  return _.str.endsWith(str, '#');
}
function check(str)
{
    var lastIndex = str.lastIndexOf('/');
    return (lastIndex != -1) && (lastIndex  == (str.length - 1));
}

Путь к будущему доказательству и / или предотвращению перезаписи существующего прототипа будет проверочной проверкой, чтобы увидеть, был ли он уже добавлен в прототип String. Вот мой взгляд на версию без регулярных выражений.

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

После всех этих долгих подсчетов ответов я нашел этот кусок кода простым и легким для понимания!

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

Это реализация конца с: String.prototype.endsWith = function (str) { return this.length >= str.length && this.substr(this.length - str.length) == str; }

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) {вернуть this.length >= str.length && this.substr(this.length - str.length) == str; }

Если вы не хотите использовать 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.prototype.endsWith = function(str) поможет нам просто вызвать метод, чтобы проверить, заканчивается ли наша строка этим или нет, ну и регулярное выражение также сделает это.

Я нашел лучшее решение, чем мое. Спасибо всем.

Для кофе

String::endsWith = (suffix) ->
  -1 != @indexOf suffix, @length - suffix.length

Не используйте регулярные выражения. Они медленные даже на быстрых языках. Просто напишите функцию, которая проверяет конец строки. В этой библиотеке есть хорошие примеры: groundjs / util.js. Будьте осторожны, добавляя функцию в String.prototype. Этот код имеет хорошие примеры того, как это сделать: groundjs / prototype.js В общем, это хорошая библиотека уровня языка: groundjs. Вы также можете взглянуть на lodash.

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

Выгоды:

  • Эта версия не просто повторно использует indexOf.
  • Наибольшая производительность на длинных струнах. Вот тест скорости http://jsperf.com/starts-ends-with/4
  • Полностью совместим со спецификацией ecmascript. Проходит испытания

Это основывается на принятом ответе @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.log(value, (this.indexOf(value, this.length - value.length) !== -1));
                return this.indexOf(value, this.length - value.length) !== -1;
            }, this);
        }
    };
}

Это требует подчеркивания - но, вероятно, может быть скорректирована, чтобы удалить зависимость подчеркивания.

Другие вопросы по тегам