首页 文章

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

提问于
浏览
1579

我如何在JavaScript中编写相应的C#的String.StartsWith

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

haystack.startsWith(needle) == true

注意:这是一个老问题,正如评论中指出的ECMAScript 2015(ES6)引入了.startsWith方法 . 但是,在撰写此更新时(2015)browser support is far from complete .

16 回答

  • 180

    以下是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 略快且简洁,但不可读 .

  • 15

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

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

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

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

    如果可能存在正则表达式控制字符出现在字符串中,则应检出Is there a RegExp.escape function in Javascript? .

  • 1681
    data.substring(0, input.length) === input
    
  • -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;
    }
    

    有关性能比较(成功和失败),请参阅http://jsperf.com/startswith2/4 . (确保检查可能胜过我的更高版本 . )

  • -3

    您可以使用ECMAScript 6的String.prototype.startsWith()方法,但它是not yet supported in all browsers . 你'll want to use a shim/polyfill to add it on browsers that don' t支持它 . 创建符合all the details laid out in the spec的实现有点复杂,本答案中定义的版本不会这样做;如果你想要忠实的垫片,请使用:

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

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

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

    http://stringjs.com/

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

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

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

    npm install string
    

    然后要求它作为 S 变量:

    var S = require('string');
    

    该网页还包含指向备用字符串库的链接,如果这个图书馆没有您喜欢的话 .

  • 21

    我只是想补充一下我对此的看法 .

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

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

    根据这里的答案,这是我现在使用的版本,因为它似乎提供了基于JSPerf测试的最佳性能(并且据我所知在功能上完整) .

    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 . 我添加了一个小的调整以获得微小的性能改进,并且之后还添加了对比较字符串为null或未定义的检查,并将其转换为使用CMS的答案中的技术添加到String原型 .

    请注意,此实现不支持Mozilla Developer Network页中提到的"position"参数,但这似乎不是ECMAScript提案的一部分 .

  • 0

    .lastIndexOf的另一种选择:

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

    对于从 haystack 的索引 0 开始的 needle 的出现,这会向后看 haystack . 换句话说,它只检查 haystack 是否以 needle 开头 .

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

    • 它不搜索整个 haystack .

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

  • 10

    您还可以通过创建自己的原型/扩展来返回数组以字符串开头的所有成员,也就是说

    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
    
  • 2

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

    • s.indexOf(starter) === 0

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

    • s.lastIndexOf(starter, 0) === 0 (看过Mark Byers的answer后补充)

    • 使用循环:

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

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

    和平

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

    Update

    正如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;
    }
    
  • 51

    如果您正在使用 startsWith()endsWith() ,那么您必须小心前导空格 . 这是一个完整的例:

    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
    
  • 576
    var str = 'hol';
    var data = 'hola mundo';
    if (data.length >= str.length && data.substring(0, str.length) == str)
        return true;
    else
        return false;
    
  • 38

    最佳方案:

    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

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

    For those that prefer to prototype it into 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;
    });
    

    Usage:

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

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

    startsWith _.startsWith(string,starts)此方法检查字符串是否以starts开头 . _( “Image.gif的”) . startsWith( “图像”)
    =>是的

  • 51

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

相关问题