JavaScript去掉空格的方法集合


Posted in Javascript onDecember 28, 2010

实现1

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

看起来不怎么样,动用了两次正则替换,实际速度非常惊人,主要得益于浏览器的内部优化。一个著名的例子字符串拼接,直接相加比用Array做成的StringBuffer还快。base2类库使用这种实现。
实现2
String.prototype.trim = function () { 
return this .replace(/^\s+/, '' ).replace(/\s+$/, '' ); 
}

和实现1很相似,但稍慢一点,主要原因是它最先是假设至少存在一个空白符。Prototype.js使用这种实现,不过其名字为strip,因为Prototype的方法都是力求与Ruby同名。
实现3
String.prototype.trim = function () { 
return this .substring(Math.max( this .search(/\S/), 0), this .search(/\S\s*$/) + 1); 
}

以截取方式取得空白部分(当然允许中间存在空白符),总共调用了四个原生方法。设计得非常巧妙,substring以两个数字作为参数。Math.max以两个数字作参数,search则返回一个数字。速度比上面两个慢一点,但比下面大多数都快。
实现4
String.prototype.trim = function () { 
return this .replace(/^\s+|\s+$/g, '' ); 
}

这个可以称得上实现2的简化版,就是利用候选操作符连接两个正则。但这样做就失去了浏览器优化的机会,比不上实现3。由于看来很优雅,许多类库都使用它,如JQuery与mootools
实现5
String.prototype.trim = function () { 
var str = this ; 
str = str.match(/\S+(?:\s+\S+)*/); 
return str ? str[0] : '' ; 
}

match是返回一个数组,因此原字符串符合要求的部分就成为它的元素。为了防止字符串中间的空白符被排除,我们需要动用到非捕获性分组(?:exp)。由于数组可能为空,我们在后面还要做进一步的判定。好像浏览器在处理分组上比较无力,一个字慢。所以不要迷信正则,虽然它基本上是万能的。
实现6
String.prototype.trim = function () { 
return this .replace(/^\s*(\S*(\s+\S+)*)\s*$/, '$1' ); 
}

把符合要求的部分提供出来,放到一个空字符串中。不过效率很差,尤其是在IE6中。
实现7
String.prototype.trim = function () { 
return this .replace(/^\s*(\S*(?:\s+\S+)*)\s*$/, '$1' ); 
}

和实现6很相似,但用了非捕获分组进行了优点,性能效之有一点点提升。
实现8
String.prototype.trim = function () { 
return this .replace(/^\s*((?:[\S\s]*\S)?)\s*$/, '$1' ); 
}

沿着上面两个的思路进行改进,动用了非捕获分组与字符集合,用?顶替了*,效果非常惊人。尤其在IE6中,可以用疯狂来形容这次性能的提升,直接秒杀火狐。
实现9
String.prototype.trim = function () { 
return this .replace(/^\s*([\S\s]*?)\s*$/, '$1' ); 
}

这次是用懒惰匹配顶替非捕获分组,在火狐中得到改善,IE没有上次那么疯狂。
实现10
String.prototype.trim = function () { 
var str = this , 
whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000' ; 
for ( var i = 0,len = str.length; i < len; i++) { 
if (whitespace.indexOf(str.charAt(i)) === -1) { 
str = str.substring(i); 
break ; 
} 
} 
for (i = str.length - 1; i >= 0; i--) { 
if (whitespace.indexOf(str.charAt(i)) === -1) { 
str = str.substring(0, i + 1); 
break ; 
} 
} 
return whitespace.indexOf(str.charAt(0)) === -1 ? str : '' ; 
}

我只想说,搞出这个的人已经不是用牛来形容,已是神一样的级别。它先是把可能的空白符全部列出来,在第一次遍历中砍掉前面的空白,第二次砍掉后面的空白。全过程只用了indexOf与substring这个专门为处理字符串而生的原生方法,没有使用到正则。速度快得惊人,估计直逼上内部的二进制实现,并且在IE与火狐(其他浏览器当然也毫无疑问)都有良好的表现。速度都是零毫秒级别的。
实现11
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; 
}

实现10已经告诉我们普通的原生字符串截取方法是远胜于正则替换,虽然是复杂一点。但只要正则不过于复杂,我们就可以利用浏览器对正则的优化,改善程序执行效率,如实现8在IE的表现。我想通常不会有人在项目中应用实现10,因为那个whitespace 实现太长太难记了(当然如果你在打造一个类库,它绝对是首先)。实现11可谓其改进版,前面部分的空白由正则替换负责砍掉,后面用原生方法处理,效果不逊于原版,但速度都是非常逆天。
实现12
String.prototype.trim = function () { 
var str = this , 
str = str.replace(/^\s\s*/, '' ), 
ws = /\s/, 
i = str.length; 
while (ws.test(str.charAt(--i))); 
return str.slice(0, i + 1); 
}

实现10与实现11在写法上更好的改进版,注意说的不是性能速度,而是易记与使用上。和它的两个前辈都是零毫秒级别的,以后就用这个来工作与吓人。
下面是老外给出的比较结果,执行背景是对Magna Carta 这文章(超过27,600字符)进行trim操作。
实现 Firefox 2 IE 6
trim1 15ms < 0.5ms
trim2 31ms < 0.5ms
trim3 46ms 31ms
trim4 47ms 46ms
trim5 156ms 1656ms
trim6 172ms 2406ms
trim7 172ms 1640ms
trim8 281ms < 0.5ms
trim9 125ms 78ms
trim10 < 0.5ms < 0.5ms
trim11 < 0.5ms < 0.5ms
trim12 < 0.5ms < 0.5ms
//String.prototype使用 
//批量替换,比如:str.ReplaceAll([/a/g,/b/g,/c/g],["aaa","bbb","ccc"]) 
String.prototype.ReplaceAll=function (A,B) { 
var C=this; 
for(var i=0;i<A.length;i++) { 
C=C.replace(A[i],B[i]); 
}; 
return C; 
}; 
// 去掉字符两端的空白字符 
String.prototype.Trim=function () { 
return this.replace(/(^[\t\n\r]*)|([\t\n\r]*$)/g,''); 
}; 
// 去掉字符左边的空白字符 
String.prototype.LTrim=function () { 
return this.replace(/^[\t\n\r]/g,''); 
}; 
// 去掉字符右边的空白字符 
String.prototype.RTrim=function () { 
return this.replace(/[\t\n\r]*$/g,''); 
}; 
// 返回字符的长度,一个中文算2个 
String.prototype.ChineseLength=function() 
{ 
return this.replace(/[^\x00-\xff]/g,"**").length; 
}; 
// 判断字符串是否以指定的字符串结束 
String.prototype.EndsWith=function (A,B) { 
var C=this.length; 
var D=A.length; 
if(D>C)return false; 
if(B) { 
var E=new RegExp(A+'$','i'); 
return E.test(this); 
}else return (D==0||this.substr(C-D,D)==A); 
}; 
// 判断字符串是否以指定的字符串开始 
String.prototype.StartsWith = function(str) 
{ 
return this.substr(0, str.length) == str; 
}; 
// 字符串从哪开始多长字符去掉 
String.prototype.Remove=function (A,B) { 
var s=''; 
if(A>0)s=this.substring(0,A); 
if(A+B<this.length)s+=this.substring(A+B,this.length); 
return s; 
};
Javascript 相关文章推荐
xml 与javascript结合的问题解决方法
Mar 24 Javascript
Document 对象的常用方法
Jul 31 Javascript
不使用中间变量,交换int型的 a, b两个变量的值。
Oct 29 Javascript
用JQUERY增删元素的代码
Feb 14 Javascript
JS实现随机乱撞彩色圆球特效的方法
May 05 Javascript
第一篇初识bootstrap
Jun 21 Javascript
深入理解JavaScript中Ajax
Aug 02 Javascript
JavaScript中利用构造器函数模拟类的方法
Feb 16 Javascript
Vue.js结合Ueditor富文本编辑器的实例代码
Jul 11 Javascript
Vue中使用ElementUI使用第三方图标库iconfont的示例
Oct 11 Javascript
JS设置自定义快捷键并实现图片上下左右移动
Oct 17 Javascript
JavaScript事件委托实现原理及优点进行
Aug 29 Javascript
js常用排序实现代码
Dec 28 #Javascript
深入理解Javascript闭包 新手版
Dec 28 #Javascript
prettify 代码高亮着色器google出品
Dec 28 #Javascript
Pro JavaScript Techniques学习笔记
Dec 28 #Javascript
使用JavaScript检测Firefox浏览器是否启用了Firebug的代码
Dec 28 #Javascript
JavaScript动态调整TextArea高度的代码
Dec 28 #Javascript
JavaScript性能陷阱小结(附实例说明)
Dec 28 #Javascript
You might like
php setcookie函数的参数说明及其用法
2014/04/20 PHP
thinkPHP5.0框架独立配置与动态配置方法
2017/03/17 PHP
PHP创建XML接口示例
2019/07/04 PHP
优化网页之快速的呈现我们的网页
2007/06/29 Javascript
javascript下判断一个元素是否存在的代码
2010/03/05 Javascript
jQuery下通过replace字符串替换实现大小图片切换
2012/05/22 Javascript
javascript静态页面传值的三种方法分享
2013/11/12 Javascript
js数组操作常用方法
2014/05/08 Javascript
JavaScript程序中实现继承特性的方式总结
2016/06/24 Javascript
Google 地图API Map()构造器详解
2016/08/06 Javascript
基于JS实现类似支付宝支付密码输入框
2016/09/02 Javascript
详解在Angularjs中ui-sref和$state.go如何传递参数
2017/04/24 Javascript
如何选择适合你的JavaScript框架
2017/11/20 Javascript
js动态添加表格逐行添加、删除、遍历取值的实例代码
2018/01/25 Javascript
nodejs更改项目端口号的方法
2018/05/13 NodeJs
vue实现百度下拉列表交互操作示例
2019/03/12 Javascript
vue使用codemirror的两种用法
2019/08/27 Javascript
解决vue v-for src 图片路径问题 404
2019/11/12 Javascript
微信小程序开发(三):返回上一级页面并刷新操作示例【页面栈】
2020/06/01 Javascript
[35:39]完美世界DOTA2联赛PWL S2 FTD.C vs Rebirth 第二场 11.22
2020/11/24 DOTA
django批量导入xml数据
2016/10/16 Python
Python决策树分类算法学习
2017/12/22 Python
OpenCV2.3.1+Python2.7.3+Numpy等的配置解析
2018/01/05 Python
Python使用pymysql从MySQL数据库中读出数据的方法
2018/07/25 Python
pymongo中group by的操作方法教程
2019/03/22 Python
Python中使用pypdf2合并、分割、加密pdf文件的代码详解
2019/05/21 Python
详解从Django Allauth中进行登录改造小结
2019/12/18 Python
python 实现在shell窗口中编写print不向屏幕输出
2020/02/19 Python
matplotlib quiver箭图绘制案例
2020/04/17 Python
Django def clean()函数对表单中的数据进行验证操作
2020/07/09 Python
通过代码实例了解Python3编程技巧
2020/10/13 Python
python归并排序算法过程实例讲解
2020/11/04 Python
洛杉矶健身中心女性专用运动服饰品牌:Marika
2018/05/09 全球购物
Redbubble法国:由独立艺术家设计的独特产品
2019/01/08 全球购物
中职生自荐信范文
2014/06/15 职场文书
未中标通知书
2015/04/17 职场文书