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

IT技术 javascript string startswith
2021-01-12 05:20:37

我将如何String.StartsWith在 JavaScript 中编写等效于 C# 的代码

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

haystack.startsWith(needle) == true

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

6个回答

您可以使用 ECMAScript 6 的String.prototype.startsWith()方法,但尚未在所有浏览器中支持您需要使用 shim/polyfill 将其添加到不支持它的浏览器上。创建一个符合规范中所有细节的实现有点复杂。如果您想要一个忠实的垫片,请使用:

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

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

警告!这些 jsperf 测试在擅长 JIT 编译的浏览器中不起作用。当操作的结果被丢弃时, Firefox 和 Chrome 等浏览器有时会识别它,因此不会执行该操作除此之外,现代 javascript 引擎使用分支预测,因此每次迭代中的测试字符串应该不同。
2021-03-27 05:20:37
注意:如果在尝试构建项目时typescript抱怨,您至少需要在 tsconfig.json 的 lib 数组中有“es2015.core”
2021-04-02 05:20:37

另一种选择.lastIndexOf

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

这会向后haystack查看needle从 index 0of开始的情况haystack换句话说,它只检查是否haystack以 开头needle

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

  • 它不会搜索整个haystack.
  • 它不会创建一个新的临时字符串然后立即丢弃它。
@rfcoder89 注意 lastIndexOf: 的第二个参数"aba".lastIndexOf ("a")正如你指出的那样是 2,但它"aba".lastIndexOf ("a", 0)是 0,这是正确的
2021-03-11 05:20:37
非常感谢。String.startsWith 在 Android 棒棒糖 WebView 上不起作用,但是这个 lastIndexOf 片段可以!!!
2021-03-19 05:20:37
@willywonka 不,如果您的 startIndex 为 0,则不是,它是从 0 pos 搜索的,这是唯一的检查。仅当 fromIndex >= str.length 时才搜索整个字符串。
2021-03-28 05:20:37
不确定@rfcoder89 正在处理哪种情况 - jsfiddle.net/jkzjw3w2/1
2021-04-07 05:20:37
使用lastIndexOf从末尾到开头搜索字符串,因此它搜索整个字符串:因此,搜索非常长的字符串时效率低下。
2021-04-09 05:20:37
data.substring(0, input.length) === input
@ANeves 我怀疑这在很大程度上取决于浏览器和使用的数据。有关实际测量,请参阅 Ben Weaver 的回答。在我当前运行的浏览器上(Windows 上的 Chrome 12.0.742)子字符串成功则成功,准备好的正则表达式失败。
2021-03-11 05:20:37
@ANeves 但是 .lastIndexOf 在一个将返回 false 的长字符串上将迭代整个字符串(O(N)),而 .substring 案例迭代一个可能更小的字符串。如果您期望多数成功或只有少量输入,则 .lastIndexOf 可能会更快 - 否则 .substring 可能会更快。如果输入比被检查的字符串长, .substring 也有引发异常的风险。
2021-03-16 05:20:37
@cobbal 也许吧。但是.lastIndexOf(input, 0)比较前 N 个字符,而.substring(0, input.length) === input计数 N,将数据子串成 N 个长度,然后比较那些 N 个字符。除非有代码优化,否则这个第二个版本不可能比另一个更快。不过不要误会我的意思,我自己永远找不到比你建议的更好的东西。:)
2021-03-24 05:20:37
@ChrisMoschini,不要忘记 Mark Byers 的解决方案lastIndexOf从索引 0 开始,而不是结束。这也让我一开始就绊倒了。尽管如此,检查字符串以什么开头是一项如此常见的任务,以至于 JavaScript 确实应该为它提供合适的 API,而不是您在此页面上看到的所有习惯用法和替代方法,无论它们多么聪明。
2021-03-24 05:20:37
我更喜欢 cobbal 的解决方案而不是 Mark 的解决方案。即使标记更快,并且使用参数是一个令人印象深刻的技巧,与子字符串相比,它也很难阅读。
2021-03-27 05:20:37

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

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

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

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

您应该查看JavaScript 中是否有 RegExp.escape 函数?如果字符串中可能出现正则表达式控制字符。

为了使表达式区分大小写使用 /^he/i
2021-04-06 05:20:37

最佳解决方案:

function startsWith(str, word) {
    return str.lastIndexOf(word, 0) === 0;
}

如果您也需要,这里是endsWith

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

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

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

用法:

"abc".startsWith("ab")
true
"c".ensdWith("c") 
true

用方法:

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
我认为你在你的函数中混淆了 lastIndexOf 和 indexOf - startsWith 应该是 return str.indexOf(word, 0) === 0;
2021-03-15 05:20:37
@RichardMatheson 使用 indexOf 的问题在于,如果它在开始时匹配失败,它将继续搜索整个字符串,其中 lastIndexOf 从单词的长度开始并返回到零。知道了?
2021-03-21 05:20:37
啊,是的,现在说得通了——我没有注意你使用的索引。很不错的把戏!
2021-03-23 05:20:37