如何在JavaScript中检查字符串是否以特定字符结尾?

示例:我有一个字符串

var str = "mystring#";


我想知道如果该字符串以#结尾。我怎么检查呢?


JavaScript中有endsWith()方法吗?
我有一个解决方案是取字符串的长度并获取最后一个字符并检查它。

这是最好的方法还是其他方法?

评论

这必须是一个相关的问题:stackoverflow.com/questions/646628/javascript-startswith

这是ES6 String.prototype.endsWith的完全符合规范的polyfill。

#1 楼

更新(2015年11月24日):

此答案最初发布于2010年(六年前)。因此,请注意以下有见地的评论:


Shauna-Google员工的更新-看起来ECMA6添加了此功能。 MDN文章还显示了polyfill。 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
T.J. Crowder-在现代浏览器上创建子字符串并不昂贵。这个答案很可能是在2010年发布的。如今,简单的this.substr(-suffix.length) === suffix方法在Chrome上最快,在IE11上与indexOf相同,并且在Firefox上仅慢4%(fergetaboutit领域):jsperf.com/endswith-stackoverflow/14当结果为假时,整体速度更快:jsperf.com/endswith-stackoverflow-when-false当然,随着ES6添加endsWith,这一点是没有意义的。 :-)


原始答案:

我知道这是一个古老的问题了……但是我也需要这个,并且我需要它可以跨领域工作浏览器,以便将每个人的答案和评论结合起来并简化一下:

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



不创建子字符串
使用本机indexOf函数以获得最快的结果
使用indexOf的第二个参数跳过不必要的比较以向前跳过
在Internet Explorer中工作
没有Regex并发症


此外,如果您不喜欢将数据填充到本机数据结构的原型中,这是一个独立版本:

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


评论


Google员工的更新-看起来ECMA6添加了此功能。 MDN文章还显示了polyfill。 developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/…

– Shauna
2013年9月11日21:18

@ lukas.pukenis会跳到末尾,只在末尾检查一个后缀实例。搜索字符串是否出现在其他位置都没有关系。

–chakrit
2013年9月26日在8:36

添加对未定义参数“后缀”时​​的情况的检查”:if(typeof String.prototype.endsWith!=='function'){String.prototype.endsWith = function(suffix){返回this.indexOf(后缀,this.length-(((suffix && suffix.length)|| 0))!== -1;};}

–曼迪普
2014-2-27在8:08



您提到的正则表达式并发症是什么?

– IcedD​​ante
2014年11月5日下午6:23

在现代浏览器中创建子字符串并不昂贵。这个答案很可能是在2010年发布的。如今,简单的this.substr(-suffix.length)===后缀方法在Chrome上最快,在IE11上与indexOf相同,在Firefox上仅慢4%(fergetaboutit领域):jsperf.com/endswith-stackoverflow / 14如果结果为假,则更快,更全面:jsperf.com/endswith-stackoverflow-when-false当然,当ES6添加endsWith时,问题就来了。 :-)

– T.J.拥挤者
15年5月6日在10:04

#2 楼

/#$/.test(str)


将在所有浏览器上运行,不需要猴子补丁String,并且在没有匹配项时不需要像lastIndexOf那样扫描整个字符串。

如果您想匹配可能包含正则表达式特殊字符的常量字符串,例如'$',则可以使用以下代码:

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


,然后可以像使用它一样this

makeSuffixRegExp("a[complicated]*suffix*").test(str)


评论


如果要检查常量子字符串,这很好且简单。

–沃伦·布兰切特(Warren Blanchet)
09年5月21日在22:50

lastIndexOf扫描所有字符串吗?我认为它会从头到尾搜索。

–汤姆·布里托(Tom Brito)
2011年4月19日在16:45



@ TomBrito,lastIndexOf仅在找不到匹配项或在开头找到匹配项时才扫描整个字符串。如果末尾有一个匹配项,则它的工作与后缀的长度成正比。是的,当str以“ asdf”结尾时,/ asdf $ /。test(str)得出true。

–迈克·塞缪尔(Mike Samuel)
2011年4月19日在16:59

@Tom Brito,这是一个正则表达式文字。该语法是从Perl借来的。请参阅developer.mozilla.org/en/Core_JavaScript_1.5_Guide/…或有关不必要的详细信息,请参阅EcmaScript语言规范的7.8.5节。

–迈克·塞缪尔(Mike Samuel)
2011年4月20日在16:21

+1为跨浏览器兼容性。已在Chrome 28.0.1500.72 m,Firefox 22.0和IE9上进行测试。

– Adrien Be
13年7月18日在15:06

#3 楼


很遗憾,不是。
if( "mystring#".substr(-1) === "#" ) {}


评论


@Anthony,嗯...所以使用.Length-1,这是什么问题? if(mystring.substr(mystring.length-1)===“#”){}在IE中工作正常。

– BrainSlugs83
2011-09-20 22:47

@ BrainSlugs83-就是问题所在:“。length-1”语法在IE中有效,而“ -1”语法则不行。这是要记住的事情,所以给安东尼+1作为小费。

–avramov
2011年11月13日在18:11

您不能使用slice()吗?在我的快速IE7测试中,它对我有用。

– alex
2012年2月8日23:00

受惊的IE。什么时候会死?

– ahnbizcad
16年4月12日在21:06

#4 楼

来吧,这是正确的endsWith实现:

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


如果没有匹配项,使用lastIndexOf只会创建不必要的CPU循环。

评论


同意我真的觉得这是提供的最高性能的解决方案,因为它具有早期中止/健全性检查,简短明了,优雅(重载字符串原型)和子字符串似乎比分解正则表达式引擎少了很多资源。

– BrainSlugs83
2011-09-20 22:52

也喜欢这种解决方案。只是函数名称拼写错误。应该是“ endsWith”。

– xmedeko
2011-10-12 12:23



@ BrainSlugs83已经有几年了,但是现在这个方法并不比上面提到的chakrit的'indexOf'方法快,而在Safari中,它要慢30%!这是针对约50个字符的字符串的失败案例的jsPerf测试:jsperf.com/endswithcomparison

–布伦特·浮士德
2011-12-5 23:28



可能应该使用===。

– Timmmm
2014年11月10日14:25

#5 楼

此版本避免创建子字符串,并且不使用正则表达式(某些正则表达式答案会起作用;其他则已损坏):

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


如果性能对您很重要,值得测试lastIndexOf是否实际上比创建子字符串更快。 (这可能取决于您所使用的JS引擎...)在匹配的情况下,它可能会更快,并且当字符串很小时-但是当字符串很大时,甚至需要回顾整个过程尽管我们并不在乎:(

检查单个字符,找到长度然后使用charAt可能是最好的方法。

评论


如果this.lastIndexOf()返回-1,则可能会遇到依赖this.length和str.length返回true的情况。添加一个测试lastIndexOf()!= -1。

– ebruchez
09年3月24日在18:44

为什么正则表达式方法坏了?

–izb
2010-09-02 14:22

@izb:早于我的尝试使用str +“ $”作为正则表达式的答案就被破坏了,因为它们可能不是有效的正则表达式。

–乔恩·斯基特(Jon Skeet)
2010-09-2 14:37

#6 楼

没有看到使用slice方法的方法。所以我就把它留在这里:

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


评论


您可以进一步简化它:return str.slice(-1)===后缀;

– Erik K.
2015年11月10日14:45

这是最好的答案。不知道为什么它没有更多的投票。

–核苷
16年7月27日在15:22

#7 楼

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


在原始字符串长度小于搜索字符串长度一且找不到搜索字符串的情况下不起作用:

lastIndexOf返回-1,然后添加搜索字符串长度,然后剩下原始字符串的长度。

可能的解决方法是

return this.length >= str.length && this.lastIndexOf(str) + str.length == this.length


评论


您已获得“在Jon Skeet答案中发现错误”徽章。有关详情,请参阅您的个人资料。

– bobince
09年3月4日在16:08

#8 楼

来自developer.mozilla.org String.prototype.endsWith()

摘要

endsWith()方法确定一个字符串是否以另一个字符串的字符结尾,并返回true或false作为

语法

str.endsWith(searchString [, position]);


参数


searchString:
字符在该字符串的末尾搜索。
位置:
在该字符串中搜索,就好像该字符串只有这么长;默认为该字符串的实际长度,并限制在该字符串的长度所建立的范围内。

说明

此方法使您可以确定一个字符串是否以另一个字符串结尾。 br />
示例

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语言规范第六版(ECMA-262)

浏览器兼容性



#9 楼

if( ("mystring#").substr(-1,1) == '#' )


-或-

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


#10 楼

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


评论


您必须为正则表达式转义序列转义字符串

–胡安·门德斯(Juan Mendes)
13年4月23日在15:41

即使使用快速语言,正则表达式也很慢。只需检查字符串的结尾即可。

–丹尼尔·努里耶夫(Daniel Nuriyev)
2014年1月5日,下午1:57

#11 楼

我不了解您,但是:

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


为什么使用正则表达式?为什么要弄乱原型? substr?来...

评论


'因为有时候在W.E.T.

–马丁·卡波迪奇(Martin Capodici)
2015年4月6日在22:47

#12 楼

使用正则表达式的另一个快速替代方法对我来说很有吸引力:

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


#13 楼

如果您使用lodash:

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


如果不使用lodash,则可以从其来源中借用。

#14 楼

我刚刚了解了这个字符串库:

http://stringjs.com/

包括js文件,然后使用S这样的变量:

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


也可以通过安装它在NodeJS中使用:

npm install string


然后将其作为S变量:

var S = require('string');


如果您不喜欢该网页,该网页还提供了指向备用字符串库的链接。

#15 楼

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

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

  return false;
}


评论


最好解释一下为什么代码可以解决问题。请参阅指南如何回答。

–brasofilo
2014年5月19日晚上8:26

应该扫描后缀参数以查找必须转义的正则表达式。使用indexOf或lastIndexOf似乎是一个更好的选择。

–vlad_tepesch
14年5月19日在8:32



如果后缀包含以下任何字符,则将不起作用:。* +?^ =!:$ {}()[] / \

– gtournie
16-10-12在8:19

#16 楼

对于这么小的问题,有这么多事情,只需使用此正则表达式




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

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




#17 楼

这个问题已经有很多年了。让我为想要使用投票最多的chakrit答案的用户添加一个重要更新。

'endsWith'函数已作为ECMAScript 6(实验技术)的一部分添加到JavaScript中。

请在这里参考:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith

因此强烈建议您添加答案中提到的本机实现的存在。

#18 楼

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


#19 楼

未来检验和/或防止覆盖现有原型的一种方法是测试检查以查看是否已将其添加到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”))。根据“ JavaScript上的Crockford-级别7:ECMAScript 5:新部件”的说法,使用typeof,“ MooTools和其他一些AJAX库会让您烦恼”,在15:50分钟。

– XP1
2012年1月11日在9:42



#20 楼

@chakrit可接受的答案是您自己执行此操作的可靠方法。但是,如果您正在寻找一个打包的解决方案,我建议看看@mlunoe指出的underscore.string。使用underscore.string,代码将是:

function endsWithHash(str) {
  return _.str.endsWith(str, '#');
}


#21 楼

经过漫长的回答,我发现这段代码简单易懂!

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


#22 楼

如果您不想使用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;
}


#23 楼

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)/));


#24 楼

这是endsWith的实现:
String.prototype.endsWith = function (str) { return this.length >= str.length && this.substr(this.length - str.length) == str; }

#25 楼

这是endsWith的实现:

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


#26 楼

这是基于@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);
        }
    };
}


这需要使用下划线js-但可以调整为删除下划线依赖性。

评论


这是一个糟糕的解决方案,如果您已经在使用下划线,则应将此epeli.github.io/underscore.string添加到您的依赖项中,并使用其实现:_.str.endsWith

– mlunoe
2014年12月23日在22:02

#27 楼

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规范。它通过了测试



#28 楼

不要使用正则表达式。即使使用快速语言,它们也很慢。只需编写一个检查字符串结尾的函数即可。这个库有很好的例子:groundjs / util.js。
小心地向String.prototype添加一个函数。这段代码提供了很好的示例:groundjs / prototype.js
通常,这是一个不错的语言级库:groundjs
您也可以看看lodash

#29 楼

所有这些都是非常有用的示例。添加String.prototype.endsWith = function(str)将帮助我们简单地调用该方法以检查我们的字符串是否以该字符串结尾,正则表达式也可以做到这一点。

我找到了比我的更好的解决方案。谢谢大家。

#30 楼

对于咖啡脚本

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