如何检查一个string“StartsWith”另一个string?

我将如何编写相当于C#的String.StartsWith在JavaScript中?

 var haystack = 'hello world'; var needle = 'he'; //haystack.startsWith(needle) == true 

注意:这是一个老问题,正如在ECMAScript 2015(ES6)的评论中指出的.startsWith方法一样。 不过,在编写本次更新(2015年) 浏览器支持的时间还远远没有完成 。

您可以使用ECMAScript 6的String.prototype.startsWith()方法,但是它尚未在所有浏览器中受支持 。 您将需要使用填充/填充将其添加到不支持它的浏览器上。 创build符合规范中规定的所有细节的实现有点复杂,并且在这个答案中定义的版本将不会执行; 如果你想要一个忠实的垫片,使用:

  • 马蒂亚斯Bynens的String.prototype.startsWith垫片 ,或
  • es6-shim ,尽可能多的ES6规格,包括String.prototype.startsWith

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

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

.lastIndexOf另一种select:

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

这从haystack的索引0开始,通过haystack向后看。 换句话说,它只会检查needle是否以needle开始。

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

  • 它不search整个haystack
  • 它不会创build一个新的临时string,然后立即丢弃它。
 data.substring(0, input.length) === input 

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

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

使用dynamicstring而不是硬编码(假设string不包含任何正则expression式控制字符):

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

你应该检查在Javascript中是否有RegExp.escape函数? 如果可能存在正则expression式控制字符出现在string中。

我只是想补充一下我的意见。

我想我们可以这样使用:

 var haystack = 'hello world'; var needle = 'he'; if (haystack.indexOf(needle) == 0) { // Code if string starts with this substring } 

这是CMS解决scheme的一个小改进:

 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库已经实现了这个function。

使用! 虽然没有可读性,但是比=== 0稍快且更简洁。

最佳解决scheme

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

也检查出underscore.string.js 。 它带有一些有用的stringtesting和操作方法,包括一个startsWith方法。 从文档:

startsWith _.startsWith(string, starts)

该方法检查string是否以starts

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

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

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

我还没有遇到使用循环的最后一个解决scheme。
令人惊讶的是,这个解决scheme的performance远远优于前三。
这里是我为了得出这个结论而进行的jsperftesting: http ://jsperf.com/startswith2/2

和平

ps:ecmascript 6(和谐)为string引入了本地startsWith方法。
只要想想,如果他们想到在初始版本中包含这个非常需要的方法,那么会节省多less时间。

更新

正如Steve指出的那样(对这个答案的第一个评论),如果给定的前缀比整个string短,上面的自定义函数将会抛出一个错误。 他已经修复了这个问题,并添加了一个循环优化,可以在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; } 

由于这是如此受欢迎,我认为值得指出的是,在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优雅地忽略的优势。

性能最好的解决scheme是停止使用库调用,只是认识到你正在使用两个数组。 手卷实现既短又快,比我在这里看到的其他所有解决scheme都快。

 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 。 (请确保你检查了可能超过我的更高版本。)

我刚刚了解到这个string库:

http://stringjs.com/

包括js文件,然后像这样使用Svariables:

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

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

 npm install string 

然后要求它作为Svariables:

 var S = require('string'); 

网页也有链接到替代string库,如果这个不喜欢你的幻想。

 var str = 'hol'; var data = 'hola mundo'; if (data.length >= str.length && data.substring(0, str.length) == str) return true; else return false; 

基于这里的答案,这是我现在使用的版本,因为它似乎给出了基于JSPerftesting的最佳性能(function完备,据我所知)。

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

这是基于startsWith2从这里: http : //jsperf.com/startswith2/6 。 我添加了一个微小的性能改进,此后还添加了一个比较string为空或未定义的检查,并将其转换为使用CMS的答案中的技术添加到string原型。

请注意,这个实现不支持在这个Mozilla开发者networking页面中提到的“position”参数,但是这似乎并不是ECMAScript提案的一部分。

我正在寻找性能,所以我通过jsperf来运行函数。 我testing了针对主题的function和search不同大小的string,看来所有的方法都performance出不同的input性能。 一般模式是性能随着searchstring长度的增加而降低。

总的来说,胜利者是最好的方法。

https://jsperf.com/javascript-string-startswith

您也可以通过创build您自己的原型/扩展到数组原型,也可以返回以string开头的数组的所有成员

 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 

如果你正在使用startsWith()endsWith()那么你必须小心前导空格。 是完整的例子:

 var Str1 = " Your String Value Here.!! "; // Starts With & Ends With leading Spaces var Str2 = Str1.trim(); // Removes All Spaces by using Trim() function Something like this --> "Your String Value Here.!!" if (Str2.startsWith("Your")) // returns TRUE if (Str2.endsWith("Here.!!")) // returns TRUE if (Str1.startsWith("Your")) // returns FALSE due to the leading spaces… if (Str1.endsWith("Here.!!")) // returns FALSE due to trailing spaces…