当前位置:  开发笔记 > 编程语言 > 正文

如何检查字符串"StartsWith"是否是另一个字符串?

如何解决《如何检查字符串"StartsWith"是否是另一个字符串?》经验,为你挑选了11个好方法。

我如何String.StartsWith在JavaScript中编写等效的C#?

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

haystack.startsWith(needle) == true

注意:这是一个老问题,正如评论中指出的ECMAScript 2015(ES6)引入了该.startsWith方法.但是,在撰写此更新时(2015年),浏览器支持还远未完成.



1> CMS..:

您可以使用ECMAScript 6的String.prototype.startsWith()方法,但并不是所有浏览器都支持它.您将需要使用填充/填充将其添加到不支持它的浏览器上.创建符合规范中列出的所有细节的实现有点复杂,并且此答案中定义的版本不会这样做; 如果你想要忠实的垫片,请使用:

Matthias Bynens的String.prototype.startsWith垫片,或者

该ES6-垫片,其衬层尽可能多的ES6规范越好,包括String.prototype.startsWith.

一旦你填充了方法(或者如果你只支持已经拥有它的浏览器和JavaScript引擎),你可以像这样使用它:

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

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


@GrahamLaight,当你说'IE'支持时,大概是你的意思是Edge.https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith#Browser_compatibility

2> Mark Byers..:

另一种选择.lastIndexOf:

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

这看起来haystackneedle从索引0的开始出现的haystack.换句话说,它只检查是否haystackneedle.

原则上,这应该比其他一些方法具有性能优势:

它不会搜索整个haystack.

它不会创建新的临时字符串,然后立即丢弃它.


@willywonka不,如果你有0 startIndex就不是,它是从0 pos搜索的,这是唯一的检查.仅当fromIndex> = str.length时才搜索整个字符串.
@ rfcoder89注意lastIndexOf的第二个参数:`"aba".lastIndexOf("a")`你指出是2,但是`"aba".lastIndexOf("a",0)`是0,这是正确的

3> cobbal..:
data.substring(0, input.length) === input


@ChrisMoschini,不要忘记Mark Byers的解决方案是`lastIndexOf`从索引0开始,而不是结束.最初,这也使我绊倒了.仍然,检查一个字符串开头是一个常见的任务,JavaScript真的应该有一个适当的API,而不是你在这个页面上看到的所有习语和替代品,无论它们多么聪明.
@cobbal也许吧.但是`.lastIndexOf(input,0)`比较前N个字符,而`.substring(0,input.length)=== input`计数N,将数据子串到N长度,然后比较这N个字符.除非有代码优化,否则第二个版本不能比另一个快.不要误会我的意思,我永远不会找到比你建议更好的东西.:)
我更喜欢cobbal的解决方案而不是Mark的解决方案.即使mark更快,并且使用params也是一个令人印象深刻的技巧,与子串相比,它很难阅读.
@ANeves我怀疑它在很大程度上取决于浏览器和使用的数据.请参阅Ben Weaver的实际测量答案.在我正在运行的浏览器上(Windows上的Chrome 12.0.742)子串赢得成功并准备正则表达式失败.
@ANeves但是.lastIndexOf对一个将返回false的长字符串将迭代整个字符串(O(N)),而.substring情况则迭代一个可能小得多的字符串.如果你期望多数成功或只有小输入,.lastIndexOf可能更快 - 否则.substring可能更快.如果输入的长度超过要检查的字符串,则.substring也会出现异常.

4> Vincent..:

没有辅助函数,只需使用正则表达式的.test方法:

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

要使用动态字符串而不是硬编码字符串(假设字符串不包含任何正则表达式控制字符):

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

你应该看看Javascript中是否有RegExp.escape函数?如果存在正则表达式控制字符出现在字符串中的可能性.



5> momomo..:

最佳方案:

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

对于那些喜欢将其原型化为String的人:

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

用法:

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


@RichardMatheson使用indexOf的问题是,如果它在开始时匹配失败,它将继续搜索整个字符串,从而lastIndexOf从单词的长度开始并回到零.得到它了?
啊,现在是有道理的 - 我没注意你使用的指数.非常好的技巧!

6> Mr.D..:

我只是想加上我对此的看法.

我想我们可以像这样使用:

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

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


如果在最开始时没有找到第一次出现,那么这种方法在继续寻找它的时间越长就开始变得越来越低效,可能会一直搜索直到它到达最后,而不是更早地放弃.由于存在低效率的可能性,因此在三种正确的方法中不受青睐.
通过@relfor比较了Mark Byers对三种不同正确方法的表现的回答.这种正确的方法不受欢迎,因为它需要搜索整个字符串.
@ Mr.D如果没有比赛?

7> 小智..:

以下是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

检查该函数是否已存在,以防将来的浏览器在本机代码中实现它,或者是否由另一个库实现.例如,Prototype Library已经实现了这个功能.

使用!=== 0不可读更快,更简洁.


这有讨论的O(N)问题http://stackoverflow.com/questions/646628/javascript-startswith/646631#comment20370021_646631

8> studgeek..:

还可以看看underscore.string.js.它附带了一堆有用的字符串测试和操作方法,包括一个startsWith方法.来自文档:

以..开始 _.startsWith(string, starts)

此方法检查是否stringstarts.

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



9> Raj Nathani..:

我最近问自己同样的问题.
有多种可能的解决方案,这里有3个有效的解决方案:

s.indexOf(starter) === 0

s.substr(0,starter.length) === starter

s.lastIndexOf(starter, 0) === 0(看过Mark Byers的回答后补充说)

使用循环:

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

我没有遇到使用循环的最后一个解决方案.
令人惊讶的是,这个解决方案的优势明显优于前3个.
这是我为达到这个结论而进行的jsperf测试:http://jsperf.com/startswith2/2

和平

ps:ecmascript 6(和谐)startsWith为字符串引入了一种原生方法.
想想如果他们想到在初始版本中包含这个非常需要的方法,那么会节省多少时间.

更新

正如Steve指出的那样(对这个答案的第一个评论),如果给定的前缀比整个字符串短,上面的自定义函数将抛出一个错误.他修复了这个问题,并添加了一个循环优化,可以在http://jsperf.com/startswith2/4上查看.

请注意,Steve包含了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;
}



10> Scheintod..:

由于这是如此受欢迎,我认为值得指出的是,这种方法在ECMA 6中有实施,并且为了准备,应该使用"官方"polyfill以防止将来出现问题和眼泪.

幸运的是,Mozilla的专家为我们提供了一个:

https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/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> Steve Hollas..:

最佳性能解决方案是停止使用库调用,并且只是认识到您正在使用两个数组.手动实现既简短又快于我在此处看到的所有其他解决方案.

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.(确保检查可能胜过我的更高版本.)

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有