JavaScript 手写trim函数

215 阅读2分钟

JavaScript 手写trim函数

1、动用了两次正则替换,实际速度非常惊人,主要得益于浏览器的内部优化

String.prototype.trim = function() {
    return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');}

2、和1很相似,但稍慢一点,主要原因是它最先是假设至少存在一个空白符。

String.prototype.trim = function() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
}

3、以截取方式取得空白部分(当然允许中间存在空白符),速度比上面两个慢一点,但比下面大多数都快。

String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/, '');
}

4、2的简化版,就是利用候选操作符连接两个正则。但这样做就失去了浏览器优化的机会,比不上实现3。

String.prototype.trim = function() {
  return  this.substring(Math.max(this.search(/\S/), 0),this.search(/\S\s*$/) + 1);
}

substring 提取字符串中介于两个指定下标之间的字符(返回的子串包括 开始 处的字符,但不包括 结束 处的字符)

search 用于检索指定的子字符串,或检索与正则表达式相匹配的子字符串。

5、浏览器在处理分组上比较无力,一个字慢。

String.prototype.trim = function() {
  var str = this;
  str = str.match(/\S+(?:\s+\S+)*/);
  return str ? str[0] : '';
}

正则表达式 (regular expression)是一个描述字符模式的对象。 ECMAScript 的 RegExp 类

表示正则表达式,而 String 和 RegExp 都定义了使用正则表达式进行强大的模式匹配和文本 检索与替换的函数。

捕获组:把正则表达式中子表达式匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用。

非捕获分组(?:exp):分组匹配之后,不需要的用?: 语法过滤子表达式内容。也就是代码匹配,但是不保存

match 会把符合的字符串筛选到数组第一个参数,按正则内的分组个数,分别输出到数组内。

eg:

var a = '    test sss   '
a.match(/\S+(\s+\S+)*/) 

输出:

var a = '    test sss   '
a.match(/\S+(?:\s+\S+)*/)

输出:

由此得出:(?:)即不捕获分组内容

6、把符合要求的部分提供出来,放到一个空字符串中。不过效率很差,尤其是在IE6中。

String.prototype.trim = function() {
  return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, '$1');
}

$1 是切割正则表达式的第一个括号

以此类推,1,1,2上就是按顺序对应小括号里面的小正则 捕获到的内容

\s*表示0个以上空格,\s+表示1个以上空格

7、和6很相似,但用了非捕获分组进行了优点,性能效之有一点点提升。

String.prototype.trim = function() {
  return this.replace(/^\s*(\S*(?:\s+\S+)*)\s*$/, '$1');
}

8、沿着上面两个的思路进行改进,动用了非捕获分组与字符集合,用?顶替了*,效果非常惊人。

String.prototype.trim = function() {
    return this.replace(/^\s*((?:[\S\s]*\S)?)\s*$/, '$1')
}

()代表分组,()匹配到的内容会分为一组,内容需要和()整体配才会匹配成功

[]代表字符集,内容匹配到[]里的任意一条规则,即为匹配成功

懒惰匹配:[\s\S]*?表示匹配任意字符,且只匹配一次

贪婪匹配:[\s\S]*没有带?号,也表示匹配任意字符,但允许匹配任意次

9、普通的原生字符串截取方法是远胜于正则替换,虽然是复杂一点。但只要正则不过于复杂,我们就可以利用浏览器对正则的优化,改善程序执行效率。

String.prototype.trim = function() {
    var str = this;
    str = str.replace(/^\s+/, '')
    for(var i = str.length - 1; i>=0; i--) {
        if(/\S/.test(str.charAt(i))) {
            str = str.substring(0, i+1);
            break;
        }
    }
    return str;
}

charAt() 方法可返回指定位置的字符

10、在写法上更好的改进版,注意说的不是性能速度,而是易记与使用上。

String.prototype.trim = function() {
    var str = this;
    str = str.replace(/^\s+/, '')
    for(var i = str.length - 1; i>=0; i--) {
        if(/\S/.test(str.charAt(i))) {
            str = str.substring(0, i+1);
            break;
        }
    }
    return str;
}