How to check if a string “StartsWith” another string?
我如何在javascript中编写C的
1 2 3 4 | var haystack = 'hello world'; var needle = 'he'; haystack.startsWith(needle) == true |
注:这是一个古老的问题,正如ECMAScript 2015(ES6)在评论中所指出的,引入了
您可以使用ecmascript 6的
- Matthias Bynens's
String.prototype.startsWith 垫片,或 - ES6垫片,其垫片尽可能多地符合ES6规格,包括
String.prototype.startsWith 。
一旦你填充了这个方法(或者如果你只支持已经拥有它的浏览器和JavaScript引擎),你就可以这样使用它:
1 2 3 4 5 | "Hello World!".startsWith("He"); // true var haystack ="Hello world"; var prefix = 'orl'; haystack.startsWith(prefix); // false |
另一个与
1 | haystack.lastIndexOf(needle, 0) === 0 |
这回顾了
原则上,这应该比其他一些方法具有性能优势:
- 它不搜索整个
haystack 。 - 它不会创建新的临时字符串,然后立即丢弃它。
1 | data.substring(0, input.length) === input |
如果没有助手函数,只需使用regex的
1 | /^He/.test('Hello world') |
要使用动态字符串而不是硬编码字符串进行此操作(假定该字符串不包含任何regexp控制字符):
1 | new RegExp('^' + needle).test(haystack) |
您应该检查一下javascript中是否有regexp.escape函数?如果有可能在字符串中出现regexp控制字符。
最佳解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
如果你也需要的话,这里是endswith:
1 2 3 | function endsWith(str, word) { return str.indexOf(word, str.length - word.length) !== -1; } |
对于那些喜欢将其原型化为字符串的用户:
1 2 3 4 5 6 7 | 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; }); |
用途:
1 2 3 4 | "abc".startsWith("ab") true "c".ensdWith("c") true |
我只是想补充一下我对此的看法。
我想我们可以这样使用:
1 2 3 4 5 6 | var haystack = 'hello world'; var needle = 'he'; if (haystack.indexOf(needle) == 0) { // Code if string starts with this substring } |
以下是CMS解决方案的一个小改进:
1 2 3 4 5 6 7 8 9 10 11 | 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 |
检查该函数是否已存在,以防将来的浏览器使用本机代码实现它,或者是否由其他库实现。例如,原型库已经实现了这个函数。
使用
还可以查看underline.string.js。它附带了一系列有用的字符串测试和操作方法,包括
startsWith
_.startsWith(string, starts) This method checks whether
string starts withstarts .
1
2 _("image.gif").startsWith("image")
=> true
我最近也问自己同样的问题。有多种可能的解决方案,以下是3种有效的解决方案:
s.indexOf(starter) === 0 s.substr(0,starter.length) === starter s.lastIndexOf(starter, 0) === 0 (见Mark Byers回答后增加)使用循环:
1
2
3
4
5
6
7
8
9function 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个。下面是我为得出这个结论而进行的jspef测试:http://jspef.com/startswith2/2
和平
ps:ecmascript 6(Harmony)为字符串引入了一种本地的
更新
正如Steve所指出的(对这个答案的第一条评论),如果给定的前缀比整个字符串短,上面的自定义函数将抛出一个错误。他修复了这个问题,并添加了一个循环优化,可以在http://jspef.com/startswith2/4上查看。
请注意,Steve提供了两种循环优化,其中第一种优化的性能更好,因此我将在下面发布该代码:
1 2 3 4 5 6 7 | 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
1 2 3 4 5 6 | if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { position = position || 0; return this.indexOf(searchString, position) === position; }; } |
请注意,在过渡到ECMA 6时,这有被优雅地忽略的优势。
最好的性能解决方案是停止使用库调用,只需认识到您使用的是两个数组。手摇实现既短又快,比我在这里看到的所有其他解决方案都快。
1 2 3 4 5 6 7 | 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://jspef.com/startswith2/4。(确保您检查了可能胜过我的更高版本。)
我刚刚了解了这个字符串库:
http://stringjs.com网站/
包括JS文件,然后使用
1 | S('hi there').endsWith('hi there') |
它也可以通过安装在nodejs中使用:
1 | npm install string |
然后要求它作为
1 | var S = require('string'); |
如果您不喜欢,网页也有指向备用字符串库的链接。
1 2 3 4 5 6 | var str = 'hol'; var data = 'hola mundo'; if (data.length >= str.length && data.substring(0, str.length) == str) return true; else return false; |
基于这里的答案,这是我现在使用的版本,因为它似乎提供了基于JSPerf测试的最佳性能(据我所知,它在功能上是完整的)。
1 2 3 4 5 6 7 8 9 | 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://jspef.com/startswith2/6。我为一个微小的性能改进添加了一个小的调整,然后还添加了对比较字符串是否为空或未定义的检查,并将其转换为使用CMS答案中的技术添加到字符串原型中。
请注意,此实现不支持此Mozilla开发者网络页面中提到的"position"参数,但这似乎不属于EcmaScript建议的一部分。
如果您使用的是
1 2 3 4 5 6 7 | var str1 =" Your String Value Here.!!"; // Starts & ends with spaces if (str1.startsWith("Your")) { } // returns FALSE due to the leading spaces… if (str1.endsWith("Here.!!")) { } // returns FALSE due to trailing spaces… var str2 = str1.trim(); // Removes all spaces (and other white-space) from start and end of `str1`. if (str2.startsWith("Your")) { } // returns TRUE if (str2.endsWith("Here.!!")) { } // returns TRUE |
您还可以通过为数组原型创建自己的原型/扩展来返回以字符串开头的数组的所有成员,也就是
1 2 3 4 5 6 7 8 9 10 11 12 | 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; }; |
并使用它:
1 2 3 | var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster']; var myResult = myArray.mySearch('Hel'); // result -> Hello, Helium |